JScrollPane acts funny inside of a JOptionsPane - java

I have tried to add a scroll view to a JOptionsPane, so that the information window can handle more text. It does add a scroll pane to the window. However, it acts funny on scrolling. The first visible text is shown clearly, but when you start scrolling, the text parts will overlap each other, until the text area is all black.
Do you have an explanation of how this can be and maybe a solution to the problem?
My code looks like this:
public void showInfoNoTranslation(String info) {
frame.requestFocusInWindow();
// create a JTextArea
JTextArea textArea = new JTextArea(info, 6, 25);
textArea.setEditable(false);
textArea.setBackground(new Color(255, 255, 255, 0));
textArea.setBorder(BorderFactory.createEmptyBorder());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
// if (textArea.getLineCount() > 5) {
JScrollPane scrollPane = new JScrollPane(textArea);
JOptionPane.showMessageDialog(_frame, scrollPane, "title", JOptionPane.INFORMATION_MESSAGE);
}

Call textArea.setOpaque(false); instead of setting it's background-color to fully transparent and it will work.
From the docs:
public void setOpaque(boolean isOpaque)
If true the component paints every pixel within its bounds. Otherwise, the component may not paint some or all of its pixels, allowing the underlying pixels to show through.
The default value of this property is false for JComponent. However, the default value for this property on most standard JComponent subclasses (such as JButton and JTree) is look-and-feel dependent.

Related

JButton over JScrollPane

I have such piece of code which shoud add button over JTextArea placed in JScrollPane. Button isn't inside scroll pane!
JScrollPane scrollPane = new JScrollPane();
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setBounds(10, 340, 375, 242);
contentPane.add(scrollPane);
JButton btnClean = new JButton();
btnClean.setBounds(340, 341, 26, 23);
contentPane.add(btnClean);
taLog = new JTextArea();
taLog.setEditable(false);
taLog.setLineWrap(true);
taLog.setFont(new Font("Arial", Font.PLAIN, 12));
scrollPane.setViewportView(taLog);
epInfo = new JEditorPane();
epInfo.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
epInfo.setFont(new Font("Tahoma", Font.PLAIN, 12));
epInfo.setContentType("text/html");
epInfo.setEditable(false);
epInfo.setBackground(null);
epInfo.setBorder(null);
epInfo.setBounds(10, 241, 375, 37);
setInfoText();
contentPane.add(epInfo);
Problem is whenever JTextArea changes its value button is not refreshed - it just dissapears - until I will drag mouse cursor over it. I suppose then some repaint() is launched.
I figured out I can add DocumentListener to JTextArea and there manually refresh button but it works until scroll bar appears in JScrollPane.
I can also use
scrollPane.getViewport().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e)
{}});
but it is invoked many times and all those refreshes are not neccesary.
Is there any reasonable (and efficient) way to check if JScrollPane changed?
Null layout is useful in this case because main window is fixed
No it is not useful.
Any time you code uses random numbers (ie to set the size/location) of components) the code is not easily maintainable.
Also I use WindowBuilder
Code generated by an IDE is not maintainable in another IDE.
Learn to use layout managers. The point of using layout managers is to avoid hard coding of numbers and to make the code maintainable in any environment.
Problem is whenever JTextArea changes its value button is not refreshed
contentPane.add(scrollPane);
...
contentPane.add(btnClean);
Swing is designed to display components in two dimension when added to the same container.
If you want components displayed in two dimension then you need to have a parent / child relationship:
- content pane
- text area
button
So the code should be something like:
textArea.setLayout( new FlowLayout(FlowLayout.RIGHT) );
//contentPane.add(btnClean);
textArea.add(btnClean);
Note: you can configure the FlowLayout to remove the spacing on the top and right.
The problem with this is that the button will cover any text that displayed in the text area.
So the better solution is to make the button external to the text area.

Trying to get an Hbox to be in front of a parent Pane

I've just been trying to put a blue box inside of a black box, to put it simply.
I have a class called DialoguePane, which extends Javafx Pane. It also has a field, an HBox that's supposed to hold buttons called actionButtonHBox, which I want to put inside of the DialoguePane.
Below is a picture of the window. The box with the label "select an action" is the DialoguePane object. Right now I'm as far as I have the two boxes inside one another. However, when I try to call the .setBackground method or use css styling to try to style the background of the Hbox, nothing changes, the background does not change. I also use toFront(), but nothing changes. I'm glad I'm at least at the point of having the boxes properly inside of one another, but I just want to change the background color of this region for formatting and design purposes.
Here's relevant parts of the Dialogue Pane's constructor
public class DialoguePane extends Pane {
private HBox actionButtonHbox;
public DialoguePane(String string) {
super();
this.resizeRelocate(480, 200, 450, 140); //Makes the DialoguePane's whole region have a width of 450, height of 140, at position x-cor 480px and y-cor 200px
this.setStyle("-fx-background-color: rgba(0, 0, 0, .95)");
//this.setDisplayableText(string);
this.makeActionButtonHbox();
}
public void makeActionButtonHbox() {
actionButtonHbox = new HBox();
System.out.println("Before: " + actionButtonHbox.backgroundProperty());
actionButtonHbox.resizeRelocate(0, 100, 400, 40); //Sets it at this position inside of the DialoguePane, a box with 400 width and 40 height. It's pretty thin.
actionButtonHbox.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, CornerRadii.EMPTY, Insets.EMPTY)));
actionButtonHbox.toFront();
System.out.println("After " + actionButtonHbox.backgroundProperty());
this.getChildren().add(actionButtonHbox);
}
There's other code that's responsible for putting a TextArea above the hbox (which is what says "Select an Action below" in the Pane, which happens in the setDisplayableText method).
So what could I do to make the background of this pane visible?

When typing into JTextArea, text in JLabel moves

I'm making a simple GUI and have a problem.
This is my code :
JFrame jFrame = new JFrame();
jFrame.setTitle("Simple Editor");
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setLocation(50,50);
jFrame.setResizable(true);
Box box = new Box(BoxLayout.Y_AXIS);
JTextArea jTextArea = new JTextArea();
jTextArea.setPreferredSize(new Dimension(470,500));
JLabel jLabel = new JLabel();
box.add(jTextArea);
box.add(jLabel);
jLabel.setText("Font type : " + Main.fontType + " font size : " + Main.size
+ " background color : " + Main.backgroundColor
+ " font color : " + Main.fontColor);
jFrame.setContentPane(box);
jFrame.pack();
jFrame.setVisible(true);
When I typing something in JTextArea, text in JLabel is moving. I can't figure out how to solve this. Maybe some component between them? Any advice and help is welcome.
This looks like an artifact of how the Box is calculating sizes and locations. Note that some components and layout managers do not use setPreferredSize, or only take it as a hint, or use it as only one part of a computation, or etc. so it cannot be depended upon as a reliable method to set the size of a component.
In this case, I would hypothesize what is going on is something like: BoxLayout generally uses minimum/maximum sizes, not preferred sizes, and the min/max of a JTextArea is computed based on its text content. As the text changes, the size is recalculated so the layout changes too.
In general if you have a text area, you should put it in a JScrollPane instead:
Box box = new Box(BoxLayout.Y_AXIS);
JTextArea jTextArea = new JTextArea();
JScrollPane jScrollPane = new JScrollPane(jTextArea);
jScrollPane.getViewport().setPreferredSize(new Dimension(470,500));
JLabel jLabel = new JLabel();
box.add(jScrollPane);
box.add(jLabel);
This way when the text content changes in the JTextArea it can simply do its thing, recalculating its size, and flow out the side of the scroll pane.
Also see How to Use Scroll Panes, How to Use Text Areas.
Per Andrew's comment, here are a couple ways to set the initial size of the scroll pane which are perhaps more reliable than setting the viewport's preferred size explicitly:
// specify rows & columns
JTextArea jTextArea = new JTextArea(20, 20);
// specify preferred scrollable viewport size
JTextArea jTextArea = new JTextArea() {
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(470,500);
}
};
jTextArea.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
jLabel.setText(jTextArea.getText());
}
});
where,
jTextArea - your name object of JTextArea class
jLabel - your name object of JLabel class
You add text in the textarea and text in the label is changing. I think, this code help you to decide your problem.

Java Swing - Scroll Pane With Custom Graphics

I currently have the code below.
public class cRunningView extends JInternalFrame {
static final int xOffset = 30, yOffset = 30;
public cRunningView() {
// Get name;
super("RUNNING", true, // resizable
false, // closable
true, // maximizable
true);// iconifiable
System.out.println("##" + "p.getName()");
// ...Then set the window size or call pack...
setSize(500, 200);
// Set the window's location.
setLocation(xOffset * 0, yOffset * 0);
JScrollPane scrollPane = new JScrollPane();
}
}
My aim is to have a JInternalFrame with a number of buttons and a box/rectangle on half of the screen.
Within this box i want to be able to draw graphics for e.g. Draw oval from x,y to x,y.
I've tried looking at examples but see to get my self more confused than i did to begin. All my code is working e.g. Showing the main GUI window and my internal frame opening but i cant seem to find a good tutuirol/starting point to do graphics within a JScrollPane.
Please note i dont have to use a JScrollPane i just thought i would be a good idea cause it would give the graphics a border round it.
Before anyone moans about the question i think it is valid AND I DONT want the code to be given to me on a plate, i'd rather know and understand what im doing so i can advance my knowledge and be able to help others !
Do i have to make another class and do
JScrollPane myPane = JScrollPane(graphicsClass)
then do everything with paint() then or is there someway to create a graphic and do it without another class?
If i do :
JScrollPane scrollPane = new JScrollPane();
Graphics temp = scrollPane.getGraphics();
temp.setColor(new Color(1, 22, 33));
temp.fillOval(60, 0, 120, 60);
scrollPane.paint(temp);
It throws errors.
Thanks
You don't do Graphics in a scrollpane. Also, don't use the getGraphics() method to do custom painting.
Custom painting is done by overriding the paintComponent() method of a JPanel or JComponent. Then if required you can add the panel to a scrollpane and add the scrollpane to your frame. Don't forget to set the preferred size of the panel so scrolling will work.
Start by reading the Swing tutorial on Custom Painting.

Multiple views in a JViewport?

Currently I have a nifty JViewport with a Jlabel set up and used as a view. I'm wondering if it's possible to use layered Jlabels as the Viewport's view. IE: I want to add new JLabels into a pre-existing Viewport.
Thanks!
EDIT: On StanislavL's advice, I'm now using a JLayeredPane within an JScrollPane. Currently there are two JLabels in the JLayeredPane, when I scroll the JScrollPane, the larger background image scrolls properly, by the smaller shipSprite remains in the same position. Any ideas how I can get them to scroll together?
public void initViewport() {
explorePort = new JScrollPane();
explorePort.setBounds(0, 0, retailWidth, retailHeight);
explorePort.setBackground(new Color(0, 100, 0));
explorePort.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
explorePort.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
ImageIcon background = Main.global.imgScaler.scaleImage(new ImageIcon("images/blankgrid.jpg"), retailWidth*2, retailHeight*2);
JLabel backSplash = new JLabel(background);
backSplash.setBounds(0, 0, retailWidth*2, retailHeight*2);
ImageIcon shipIcon = Main.global.imgScaler.scaleImage(new ImageIcon("images/ship.png"), Main.global.nodeWidth, Main.global.nodeHeight);
JLabel shipSprite = new JLabel(shipIcon);
shipSprite.setBounds(100, 100, Main.global.nodeWidth, Main.global.nodeHeight);
Main.global.gamePanel.add(backSplash, 0);
explorePort.setViewportView(backSplash);
Main.global.gamePanel.add(shipSprite, 1);
Main.global.gamePanel.add(explorePort, 2);
//explorePort.addMouseListener(this);
Main.global.gameFrame.addKeyListener(new ListenKey());
}
Use Layered pane to add multiple lables to container and place the container in JScrollPane
http://docs.oracle.com/javase/tutorial/uiswing/components/layeredpane.html

Categories