I have a typical IDE style window with a top JMenuBar and JToolBar,
a large center console and a bottom status bar.
Here are the main parts of the code:
mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
. (JMenuBar and JToolBar)
.
mainPanel.add(topPanel, BorderLayout.NORTH);
cardPanel = new JPanel();
cardPanel.setLayout(cardLayout);
.
.
Dimension minDimension = new Dimension(680, 400);
Dimension maxDimension = new Dimension(750, 800);
JPanel centerPanel = new JPanel();
centerPanel.setMinimumSize(minDimension);
centerPanel.setPreferredSize(minDimension);
centerPanel.setMaximumSize(maxDimension);
centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.Y_AXIS));
centerPanel.add(cardPanel);
mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(statusBar, BorderLayout.SOUTH);
I want to be able to control the sizing of the whole window,
with a minimum and maximum size.
I thought I could have the 'centerPanel' JPanel as a BoxLayout,
so I could have some control over it, but as it is, I can't
control the sizing of the window at all.
I tried to make the 'mainPanel' use a BoxLayout, instead of a BorderLayout, but there
where too many issues.
Is the main BorderLayout causing it to "ignore" the sizing?
I know that the parts, other than the center, have some sizing
control, that's why I tried to use a BoxLayout in the center.
Is it possible to keep the BorderLayout, and get it to work,
with some other modifications, or would I need to switch to some other Layout Manager?
Thanks!
Related
In most of the GUI programs, when the user resizes it, the components of the program, such as text fields, buttons, etc. tend to increase or decrease their size depending on the decisions of the user. I'm trying to implement this idea into my GUI program. I'm a little bit lost about how I can do it. By the way, I created my program without the usage/help of the Eclipse Swing or Netbeans' GUI.
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
public class CodeReviewerFrame extends JFrame {
EditorAreaPanel display = new EditorAreaPanel();
// FileOptionsPanel fileOptionsPanel = new FileOptionsPanel( display );
JPanel p = new JPanel();
JPanel panel = new JPanel();
public CodeReviewerFrame(String title) throws IOException {
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(1500, 1000));
setLayout(new BorderLayout());
ImageIcon img = new ImageIcon("icon.png");
setIconImage(img.getImage());
p.setLayout(new BorderLayout());
p.add(new HomeOptionsPanel(display), BorderLayout.LINE_START);
p.add(new NewCommentPanel(display), BorderLayout.CENTER);
p.add(new CommentOptionsPanel(display), BorderLayout.LINE_END);
add(p, BorderLayout.PAGE_START);
panel.setLayout(new BorderLayout());
panel.add(new FileExplorerPanel(), BorderLayout.LINE_START);
panel.add(new FileOptionsPanel(display), BorderLayout.CENTER);
panel.add(new CommentShowPanel(display), BorderLayout.LINE_END);
add(panel, BorderLayout.CENTER);
pack();
setResizable(true);
setVisible(true);
/**
* Everything Under This is experimental
*/
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
//add ( fileOptionsPanel, constraints );
}
}
There are components on each Panel that have been added, such as buttons in HomeOptionsPanel, huge JTextArea in the center of FileOptionsPanel plus four buttons up on the JTextArea, etc. Should I use new Layout type, or commands known as "repaint/revalidate," or implement changeListener? And should I only implement the code to the JFrame, or do it for each of the JPanels?
The behaviour of your UI upon window resizing depends (also) on the Layout Manager you are using.
Some Layout Managers (like BorderLayout) resize the components when the windows is resized, while others (like FlowLayout) don't.
It is not clear what LM you are using inside your panels, but most likely your issue stands in there.
I am trying to set the sizes of my JButtons in a JPanel with BoxLayout correctly, but the behavior is beyond weird.
It will take the height from JButton.setPreferredSize, but completely ignore the width. This also only works when all buttons are set to the same height. As soon as one is smaller, it will revert all of them to some random minimum size (which isn't even the same for all buttons)
My code is this:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 500);
JPanel rightPanel = new JPanel();
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
JButton bBookmarks = new JButton("Bookmarks");
bBookmarks.setPreferredSize(new Dimension(200, 100));
//more buttons with same size
leftPanel.add(bBookmarks);
//more buttons
JSplitPane mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftPanel, rightPanel);
mainPanel.setDividerLocation(200);
frame.add(mainPanel);
frame.setResizable(false);
frame.setVisible(true);
This creates this image.
The middle button is always wider than the rest as well. Using frame.pack() doesn't do anything except resizing the frame because the right panel is empty.
What am I doing wrong?
Edit: Should look like this:
Divide and conquer: break the design into small, easy to layout containers. In this case do not place the buttons directly in the left (BoxLayout) container but in a nested JPanel using GridLayout manager.
This ensures that all buttons have the same size:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
//add all buttons to a panel using a GridLayout which shows all components having the same size
JPanel buttons = new JPanel(new GridLayout(0,1));
JButton bBookmarks = new JButton("Bookmarks"); buttons.add(bBookmarks);
JButton bPlotter = new JButton("Plotter"); buttons.add(bPlotter);
JButton bShips = new JButton("Ships"); buttons.add(bShips);
//add buttons and text area to a panel using BoxLayout
JPanel leftPanel = new JPanel();
leftPanel.setPreferredSize(new Dimension(100,400));
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.PAGE_AXIS));
leftPanel.add(buttons);
leftPanel.add(new TextArea(10,30));
JPanel rightPanel = new JPanel();
rightPanel.setPreferredSize(new Dimension(600,400));
rightPanel.add(new JLabel("right pane"));
JSplitPane mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true, leftPanel, rightPanel);
frame.add(mainPanel);
frame.pack();
frame.setVisible(true);
I have been working on this for hours. I honestly cannot figure it out. I have JTextArea's inside a JSplitPane which is inside a JPanel with a JButton and all that is put in my JFrame. I am using Layout managers. I have tried using pack(). I have tried using preferred sizes. Without the JPanel my button does not display in the proper location or switch buttons in other Tabs. With the JPanel it cuts off all my text, stops the scroll function(yes I have tried setting the TextAreas to always have horizontal and vertical scroll bars...does not solve the problem where text just stops wrapping for no apparent reason).
public static void main(String[] args) throws IOException
{
JFrame frame = new JFrame();
Deck blackjack = new Deck(Deck.TYPE[0]);
JTextArea textBlackjackUnshuffled = new JTextArea();
JTextArea textBlackjackShuffle = new JTextArea();
JButton shuffleButtonBlackjack = new JButton(new ImageIcon(ImageIO.read(new File("res/shuffle.png"))));
JToolBar toolBarBlackjack = new JToolBar("Blackjack");
JSplitPane splitPaneBlackjack = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JPanel panel = new JPanel();
JTabbedPane tabbedPaneBlackJack = new JTabbedPane();
JTabbedPane tabbedPaneCanasta = new JTabbedPane();
JTabbedPane tabbedPanePinochle = new JTabbedPane();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
textBlackjackUnshuffled.setColumns(10);
textBlackjackUnshuffled.setLineWrap(true);
textBlackjackUnshuffled.setWrapStyleWord(true);
textBlackjackUnshuffled.setEditable(false);
textBlackjackUnshuffled.setFont(new Font("DejaVu Sans", Font.PLAIN, 100));
textBlackjackUnshuffled.append(blackjack.toString());
textBlackjackShuffle.setColumns(10);
textBlackjackShuffle.setLineWrap(true);
textBlackjackShuffle.setWrapStyleWord(true);
textBlackjackShuffle.setEditable(false);
textBlackjackShuffle.setFont(new Font("DejaVu Sans", Font.PLAIN, 100));
textBlackjackShuffle.append(blackjack.toString());
shuffleButtonBlackjack.setBorderPainted(false);
shuffleButtonBlackjack.setFocusPainted(false);
shuffleButtonBlackjack.setContentAreaFilled(false);
splitPaneBlackjack.add(new JScrollPane(textBlackjackUnshuffled));
splitPaneBlackjack.add(new JScrollPane(textBlackjackShuffle));
panel.add(splitPaneBlackjack, BorderLayout.CENTER);
panel.add(shuffleButtonBlackjack, BorderLayout.PAGE_END);
tabbedPaneBlackJack.addTab("Blackjack", panel);
frame.add(tabbedPaneBlackJack);
frame.setSize(new Dimension(Toolkit.getDefaultToolkit().getScreenSize()));
frame.setVisible(true);
}
You're adding the JScrollPanes to the panel in BorderLayout positions, but have not set the layout manager of panel to BorderLayout. In this situation, panel will be using JPanel's default layout manager, FlowLayout, a manager which is not smart enough to respect the scroll pane's preferred sizes.
Your code needs:
panel.setLayout(new BorderLayout());
I am trying to make a boxlayout filled with a Jlabel and 3 radio buttons in descending order. The program compiles fine but then errors out with the error BoxLayout cant be shared. I have seen people saying this error is because they are trying to attach it to a jframe, but in this case it is the jpanel being given the layout not a frame. This is the segment of code that compiles the window.
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel effortButtons = new JPanel();
JPanel skillButtons = new JPanel();
effortButtons.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
skillButtons.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
effortButtons.add(effortHeader);//this is what gives the error
effortButtons.add(oneEffort);
effortButtons.add(twoEffort);
effortButtons.add(threeEffort);
skillButtons.add(skillHeader);
skillButtons.add(oneSkill);
skillButtons.add(twoSkill);
skillButtons.add(threeSkill);
mainPanel.add(effortButtons, BorderLayout.WEST);
mainPanel.add(skillButtons, BorderLayout.EAST);
mainPanel.add(studentName, BorderLayout.NORTH);
mainPanel.add(next, BorderLayout.SOUTH);
add(mainPanel);
pack();
// xxxxxxxxxxxxx xxxxxxxxx
effortButtons.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
You have to pass into the BoxLayout constructor the component that is getting the layout. So this should be:
effortButtons.setLayout(new BoxLayout(efforButtons, BoxLayout.Y_AXIS));
Likewise for our other JPanel -- change it to:
skillButtons.setLayout(new BoxLayout(skillButtons, BoxLayout.Y_AXIS));
Per the BoxLayout API:
public BoxLayout(Container target, int axis)
target - the container that needs to be laid out
I'm still trying to learn how layout managers work. I made a Frame with two JPanels.
The first one contains a textArea with a boxLayout.
The second one contains a flow layout with a button.
I set the preferredSize of each panel accordingly, packed them, but got unexpected results.
import java.awt.*;
import javax.swing.*;
public class LayoutMgrTest
{
public static void main(String[] args)
{
TableBasic frame = new TableBasic();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.setVisible(true);
frame.getContentPane().setLayout(new GridLayout(2,1));
JPanel controlPane = new JPanel();
JPanel buttonPane = new JPanel();
controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
controlPane.setPreferredSize(new Dimension(200, 200));
controlPane.add(new JScrollPane(new JTextArea()));
buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPane.setPreferredSize(new Dimension(100,20));
buttonPane.add(new JButton("Button1"));
buttonPane.add(new JButton("Button2"));
frame.getContentPane().add(controlPane, BorderLayout.NORTH);
frame.getContentPane().add(buttonPane, BorderLayout.SOUTH);
frame.setSize(new Dimension(500,500));
frame.pack();
}
}
Whatever I do, if I use a grid Layout, it seems to always allocate half of the available space to each control. I have been told that:
The height of each row is dependent on the height of each component
added in each row.
The buttonpane's height is 20. It's allocating much more than that to it:
What's wrong with this code?
I would like to leave the two JPanels intact please. It's easy to simply add the textbox and the buttons directly to the frame, but I need to do it with JPanels (because I will be adding borders and other things).
That's the result of using GridLayout as layout manager. Change it to BorderLayout:
frame.getContentPane().setLayout(new BorderLayout());
For example, this code (I changed a little as possible from the original):
import java.awt.*;
import javax.swing.*;
public class LayoutMgrTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
//frame.setVisible(true);
//frame.getContentPane().setLayout(new BorderLayout());
JPanel controlPane = new JPanel();
JPanel buttonPane = new JPanel();
controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
controlPane.setPreferredSize(new Dimension(200, 200));
controlPane.add(new JScrollPane(new JTextArea()));
buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPane.setPreferredSize(new Dimension(100,40));
buttonPane.add(new JButton("Button1"));
buttonPane.add(new JButton("Button2"));
frame.add(controlPane, BorderLayout.NORTH);
frame.add(buttonPane, BorderLayout.SOUTH);
//frame.setSize(new Dimension(500,500));
frame.pack();
frame.setVisible(true);
}
}
Generates this frame:
I set the preferredSize of each panel accordingly,
That is another problem. You should NOT set the preferred size. That is the job of the layout manager. Just add your components to the panels and let the layout manager do its job.
Most compnents have a default preferred size. For some you need to give it a little tip.
For example when using a text area you would give a "suggested" preferred size by using:
JTextArea textArea = new JTextArea(rows, columns);
If you use LayoutManager, you should not set a size on a component except the frame.
the size for the components is calculated from the different layout managers.
you find more infos at http://download.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html
in your code, you can add the panel with the textarea to BorderLayout.CENTER. this should solve your problem. the component in BorderLayout.CENTER takes the whole space, except the space needed for the components in NORTH, EAST, SOUTH and WEST.