I have a JTextArea inside of a JPanel that is then placed into the JScrollPane. When the JPanel that contains the JScrollPane is first show the JScrollPane shows up but not the contents. As soon as the JFrame is resized the contents show up.
JTextArea area = new JTextArea(6, 20);
area.setText("Some test text");
JPanel panel = new JPanel(new BorderLayout());
panel.add(area, BorderLayout.CENTER);
JScrollPane pane = new JScrollPane();
pane.setBounds(20, 20, WIDTH - 40, 300 - 40);
pane.setPreferredSize(new Dimension(WIDTH - 40, 300 - 40));
add(pane);
pane.setViewportView(panel);
pane.setBounds(20, 20, WIDTH - 40, 300 - 40);
pane.setPreferredSize(new Dimension(WIDTH - 40, 300 - 40));
Those two lines of code doen't make sense (although they are not the cause of your problem)
The first line is used when you are using a "null layout".
The second is used when you are using layout managers.
They should not be used together.
The second is preferred since you should be using layout managers.
In the application different JPanels are swapped out in a manner similar to a slide-show. So something like this would be found in the code:
panel.remove(slide1);
panel.add(slide2);
panel.repaint();
The problem being that all of the contents of the second slide, slide2, would not show up. The solution is to add
frame.validate();
Where frame is the parent window of panel.
new JScrollPane(panel);
I believe that you need to add the panel to the scroll pane constructor.
Related
I have a JTextArea, and I want to add a JMenuBar to it, but it doesn't seem to work.
ta = new JTextArea();
ta.setBackground(Color.RED);
// ta.setLayout(null); I tried with a null layout and
non-null
pane = new JScrollPane(ta);
pane.setBounds(Main.WIDTH - (Main.WIDTH - 20), Main.HEIGHT - (Main.HEIGHT - 20), Main.WIDTH - 60, Main.HEIGHT - 500);
bar = new JMenuBar();
bar.setBounds(0, 0, ta.getWidth(), 20); // This won't be there if
// there is a non-null layout.
ta.add(bar); // I also tried pane.add(bar); that didn't work either.
Is there any way to add JMenuBar to JTextArea?
Put the JTextArea into a JScrollPane -- always
Add the JScrollPane to the BorderLayout.CENTER position of a JPanel that uses BorderLayout
Add the JMenuBar to the BorderLayout.PAGE_START position of the same BorderLayout using JPanel
Done
e.g.,
JTextArea ta = new JTextArea(40, 20); // give columns and rows
JScrollPane scrollPane = new JScrollPane(ta);
JPanel borderLayoutPanel = new JPanel(new BorderLayout());
borderLayoutPanel.add(scrollPane, BorderLayout.CENTER);
JMenuBar menuBar = new JMenuBar();
// add menu's to the menu bar here
borderLayoutPanel.add(menuBar, BorderLayout.PAGE_START);
Side notes:
The code where you call, ta.getWidth() is likely returning a width value of 0, since it appears to be called before the JTextArea has been rendered.
You almost never want to add components directly to the JTextArea itself as that potentially interferes with the functioning of the text area.
I would like to achieve the below layout.
There are 6 panels. The 4 buttons at the top are one panel, and the 3 buttons at the right side of the image are also in one panel. Apart from those two there are 4 other panels as indicated by the borders. I tried the below code but displays everything in a scattered way.
mainPanel.add(topToolBarPanel,BorderLayout.PAGE_START);
mainPanel.add(lefsideToolBarPanel,BorderLayout.LINE_START);
mainPanel.add(descriptionPanel,BorderLayout.LEFT);
mainPanel.add(mapPanel,BorderLayout.CENTER);
mainPanel.add(propertiesPanel,BorderLayout.EAST);
mainPanel.add(tablePanel,BorderLayout.PAGE_END);
How can I achieve the design as shown in the image? I need all the panels to be arranged inside that mainPanel. I cannot use null layout though. Please advice.
After trashgod's answer :
JPanel gridPanel = new JPanel(new GridLayout(1, 0));
gridPanel.add(jInternalFrame1);
gridPanel.add(descriptionPanel);
mainPanel.add(gridPanel, BorderLayout.LINE_START);
mainPanel.add(topToolBarPanel,BorderLayout.PAGE_START);
mainPanel.add(tablePanel,BorderLayout.PAGE_END);
mainPanel.add(mapPanel,BorderLayout.CENTER);
mainPanel.add(PropertiesPanel,BorderLayout.LINE_END);
What I get :
Add lefsideToolBarPanel and descriptionPanel to a panel having GridLayout; add the new panel to the BorderLayout.
Panel p new Panel(new GridLayout(1, 0));
p.add(lefsideToolBarPanel);
p.add(descriptionPanel);
//mainPanel.add(lefsideToolBarPanel, BorderLayout.LINE_START);
//mainPanel.add(descriptionPanel, BorderLayout.LEFT);
mainPanel.add(p, BorderLayout.LINE_START);
There is no BorderLayout.LEFT. See also A Visual Guide to Layout Managers.
Addendum: Your updated question shows elements of topToolBarPanel, which should be added to PAGE_START, rather than LINE_START.
//mainPanel.add(topToolBarPanel,BorderLayout.LINE_START);
mainPanel.add(topToolBarPanel,BorderLayout. PAGE_START);
The width of the propertiesPanel and height of the tablePanel need to be increased. I used setSize()…
For the propertiesPanel, you can override getPreferredSize(), as discussed here. For the tablePanel, override getPreferredScrollableViewportSize() to customize the size of the table's enclosing JScrollPane, for example.
I suggest using a JLabel as your "layout" to use exact positioning of yout objects with setBounds(x, y, width, height). It would look similar to this :
JButton button = new JButton("Text or Image");
JLabel backgr = new JLabel();
JFrame frame = new JFrame("JLabel as Layout");
button.setBounds(100, 200, 340, 40);
backgr.add(button);
frame.add(backgr);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocation(40, 40);
frame.validate();
frame.setVisible(true);
I know that this is just a quick example for you, but I think it should do for explanation... so just add everything on the backgr JLabeland your good to go. Quick and dirty example but the a way to go.
I was trying out JLayeredPane. So, in the following code, I created a JLayeredPane and a JLabel. I added the label to the layered pane, which I added to a JPanel. This panel was then added to a JFrame.
public static void main(String[] args) {
frame = new JFrame("LayeredPane Example");
frame.setPreferredSize(new Dimension(500,500));
layeredPane = new JLayeredPane();
layeredPane.setPreferredSize(new Dimension(400, 400));
JLabel label = new JLabel("Label on LayeredPane");
label.setLocation(200, 200);
System.out.println("Width " + label.getWidth() );
label.setBounds(20, 20, 400, 40);
layeredPane.add(label);
layeredPane.setLayer(label, 10, 1);
frame.setLayout(new BorderLayout());
JPanel panel = new JPanel();
panel.add(layeredPane);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
Now the problem is that if I do not have the statement label.setBounds(20, 20, 400, 40);, then the label does not appear on the layered pane. This raises two questions:
Why is setBounds so important?
Probably a part of my previous questions answer, the label had an initial height and width of 0 before setting bounds, which might be the reason setBounds is important. In that case, I want to know how can I determine appropriate bounds for a Swing component when I am adding it to a JLayeredPane. (If my bounds are less than the appropriate size of the component, the component will appear hidden)
Edit:
The first question was answered earlier in more detail here.
Regarding:
Why is setBounds so important: A JLayeredPane uses essentially a null layout, and whenever you use null layouts, you the coder are completely responsible for both the size and position of the components that you add. That's simply the rules of this layout.
How to determine the appropriate bounds: One thing I've done is simply to let the component tell me what its preferredSize is and then use it for its size:
myJLabel.setSize(myJLabel.getPreferredSize());
Another thing I've done is to use non-opaque JPanels for each layer of my JLayeredPane, give these JPanels appropriate layouts and then add my components to the appropriate layer JPanel. I then use a listener to be sure that the layer JPanel's size matches that of its JLayeredPane container.
I have got a window that should display the following:
JLablel "Have you used GUI before?" on the top, centered
two radioButtons "Yes" and "No" below it, somewhat in the center, a little bit towards the left
a JButton "NEXT" in the bottom-right corner
All three elements should have green font and darkGrey background.
The problem is that the window which is showing up, does not look like I would like it to.
And this is my code:
yesButton = new JRadioButton(yes);
//yesButton.setMnemonic(KeyEvent.VK_B); // doesn't work?
yesButton.setActionCommand(yes);
noButton = new JRadioButton(no);
// noButton.setMnemonic(KeyEvent.VK_C); // doesn't work?
noButton.setActionCommand(no);
ButtonGroup group = new ButtonGroup();
group.add(yesButton);
group.add(noButton);
nextButton = new JButton("NEXT");
nextButton.setActionCommand(next);
yesButton.addActionListener(this);
noButton.addActionListener(this);
nextButton.addActionListener(this);
JPanel radioPanel = new JPanel(new GridLayout(0, 1));
radioPanel.add(yesButton);
radioPanel.add(noButton);
add(radioPanel, BorderLayout.WEST);
// setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
// radioPanel.setBorder(new EmptyBorder(250, 250, 20, 20));
// there is no difference between the above two, right?
String q = "Have you used GUI before?";
JPanel area = new JPanel(new BorderLayout());
area.setBackground(Color.darkGray);
JLabel textLabel2 = new JLabel("<html><div style=\"text-align: center;\">"
+ q + "</html>", SwingConstants.CENTER);
textLabel2.setForeground(Color.green);
Font font2 = new Font("SansSerif", Font.PLAIN, 30);
textLabel2.setFont(font2);
//textLabel2.setBorder(new EmptyBorder(0, 0, 250, 0)); //top, left, bottom, right
area.add(textLabel2, BorderLayout.NORTH);
area.add(nextButton, BorderLayout.EAST);
add(area, BorderLayout.CENTER);
I feel I'm nearly there, thanks for any help!
--EDIT--
A screenshot:
You need to use nested panels.
for the BorderLayout.NORTH you can add the JLabel directly. You will need to set the horizontal text alignment to center.
for the radio buttons you can create a JPanel with a FlowLayout and then add the buttons to the panel and add the panel to the CENTER.
for the button you add the button to a panel using a FlowLayout that is right aligned, then add the panel to the SOUTH.
There are other choices. You could also use a Vertical BoxLayout as the layout of the main panel and then add child panels to it.
You won't be able to get much control with just a BorderLayout. Try something else like MigLayout or one of the other many many layout managers Java has (GridBag, Box, etc).
In MigLayout it would look something like:
area.setLayout(new MigLayout("fill"));
area.add(textLabel2, "wrap");
area.add(radioPanel, "wrap");
area.add(nextButton, "tag right");
Simply put, I would like to make java do what I want but I can not get my head around the layout manages for anything other that auto resizing to what it feels like doing.
All I would like is a fixed height "footer" and the top "main" area to auto resize in height to whatever the window is.
With the horizontal for both having a min size but no max size.
Is it possible (I know it is but it feels like it isn't atm!)
Please help!
many thanks
Edit: Updated with advice from below:
public JPanel getPanDescription()
{
JPanel masterPane = new JPanel();
masterPane.setMaximumSize(new Dimension(999999,400));
masterPane.setMinimumSize(new Dimension(100,400));
<snip>
return masterPane;
}
this.panDescription = getPanDescription();
this.panPage = new JPanel(new BorderLayout());
this.panPage.add(this.searchPanel, BorderLayout.CENTER);
this.panPage.add(this.panDescription, BorderLayout.PAGE_END);
Works just fine, but depending on the content of panDescription, depends on its size.
It still just resizes to the content :S
Use a BorderLayout. Add your footer to the bottom location. Set the max size of the footer to the fixed height you want and a width bigger than your window will ever be.
JPanel mainPanel = new JPanel();
JPanel footerPanel = new JPanel();
this.setLayout(new BorderLayout());
this.add(mainPanel);
this.add(footerPanel, BorderLayout.SOUTH);
footerPanel.setMaximumSize(new Dimension(10000, 100));
footerPanel.setPreferredSize(new Dimension(600, 100));
footerPanel.setMinimumSize(new Dimension(1, 100));