GUI, BoxLayout adding a panel - java

Studying BoxLayout and GUI in general. I want to place a panel on a frame. Later I'll add an identical panel and will test BoxLaoyout. But I can't understand why this code produces not a panel sized 200x400 but just a red point in the middle of the left side of the frame (with coordinates about (300,0)).
public class View extends JFrame {
public View(){
this.setPreferredSize(new Dimension(600, 600));
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.pack();
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.BLACK);
JPanel p1 = new JPanel();
p1.setSize(200, 400);
p1.setBorder(border);
p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
panel.add(p1);
this.add(panel);
this.setVisible(true);
}
}

The layout manager (BoxLayout) is using the preferred size of the components of the container it is managing. By default, the preferred size of a empty JPanel is 0x0, adding in the border has produced a preferred size closer to 2x2
When using layout managers, calling setSize is meaningless, as the layout manager will override anything you specify when the container is revalidate
Updated
It would appear that the combination of both BoxLayouts seems to be playing against you. If I remove the second BoxLayout from p1, it seems to work okay.
Also, BoxLayout seems to want to work with the maximum size of the component...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.WindowConstants;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
public class View extends JFrame {
public View() {
this.setPreferredSize(new Dimension(600, 600));
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.pack();
JPanel panel = new JPanel();
panel.setBorder(new LineBorder(Color.BLUE));
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
Border border = BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.RED, Color.BLACK);
JPanel p1 = new JPanel() {
public Dimension getMaximumSize() {
return new Dimension(200, 400);
}
};
p1.setBorder(border);
p1.setLayout(new BoxLayout(p1, BoxLayout.Y_AXIS));
panel.add(p1);
this.add(panel);
this.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new View();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}

Related

I want to use a BoxLayout in a ScrollPane that has an ArrayList of Panels

When I set the outpanel into a BoxLayout then the panel disappears. However the scrollbar shows that indicates my panel in ArrayList are in the right position.
I am totally new to Java so I'll appreciate any comments.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.*;
import javax.swing.*;
public class gui extends JFrame{
int ctr=0, top=5;
public List<JPanel> o_panels = new ArrayList<JPanel>(); //Your List
public gui(){
super("MCC");
setLayout(null);
//Output panel for the results
JPanel outpanel = new JPanel();
outpanel.setBackground(Color.blue);
outpanel.setVisible(true);
outpanel.setLayout(new BoxLayout(outpanel, BoxLayout.PAGE_AXIS));
//Scroll pane
JScrollPane scrollPane = new JScrollPane(outpanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(0,0,780,400);
add(scrollPane);
//result panel
//creating and adding panels in to the array list
while(ctr<=4){
JPanel label1 = new JPanel();
label1.setPreferredSize(new Dimension(600,100));
o_panels.add(label1);
outpanel.add(o_panels.get(ctr));
ctr++;
}
}
public void runGui(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(800,600);
this.setVisible(true);
this.setResizable(false);
//i call this on the other class
}
}
There is, not much, wrong with your code, the problem is, you've not established any means by which you can see what you've been adding
Have a look at this...
while (ctr <= 4) {
JPanel label1 = new JPanel();
label1.setPreferredSize(new Dimension(600, 100));
o_panels.add(label1);
outpanel.add(o_panels.get(ctr));
ctr++;
}
All the panels are the same color and you've added nothing to them, so how could you possible know if they were been added or layout correctly...
I simple added label1.setBorder(new LineBorder(Color.RED)); and got this result...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class Test extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
Test test = new Test();
test.runGui();
}
});
}
int ctr = 0, top = 5;
public List<JPanel> o_panels = new ArrayList<JPanel>(); //Your List
public Test() {
super("MCC");
//Output panel for the results
JPanel outpanel = new JPanel();
outpanel.setBackground(Color.blue);
outpanel.setVisible(true);
outpanel.setLayout(new BoxLayout(outpanel, BoxLayout.PAGE_AXIS));
//Scroll pane
JScrollPane scrollPane = new JScrollPane(outpanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(0, 0, 780, 400);
add(scrollPane);
//result panel
//creating and adding panels in to the array list
while (ctr <= 4) {
JPanel label1 = new JPanel();
label1.setPreferredSize(new Dimension(600, 100));
label1.setBorder(new LineBorder(Color.RED));
o_panels.add(label1);
outpanel.add(o_panels.get(ctr));
ctr++;
}
}
public void runGui() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
this.setVisible(true);
// this.setResizable(false);
setLocationRelativeTo(null);
}
}
Also have a look at Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
And you really should avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify

GridBagLayout and drawing

I'm making a small game and at the beginning i want to have JCheckBox for choosing the language(after that they are few more of them for setting the game) and above that a jlabel with picture with name of the game OR draw an image there, the problem is that i dont know any other way how to center the panel with checkboxes then to use GridBagLayout and when i use this, i cannot draw anything to the frame, id like to also remove those grey lines around the checkboxes if its possible, appreciate any help, thanks.
This is my second question here and i cant add images yet so here is a link to the picture :
here is code for the frame
private GamePlan plan;
private JFrame frame;
private String language;
private JPanel panel;
private JCheckBox englishBox;
private JCheckBox germanBox;
public Settings(GamePlan plan){
this.plan = plan;
frame = new JFrame();
frame.setSize(600, 500);
frame.setLocation(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.setResizable(false);
frame.setVisible(true);
panel = new JPanel(new GridLayout(2, 1));
englishBox = new JCheckBox("English", false);
germanBox = new JCheckBox("German", false);
englishBox.addActionListener(new EnglishLanguage());
germanBox.addActionListener(new GermanLanguage());
panel.add(englishBox);
panel.add(germanBox);
englishBox.setOpaque(false);
germanBox.setOpaque(false);
panel.setOpaque(false);
frame.add(panel);
frame.getContentPane().setBackground(new Color(216,252,202));
}
" the problem is that i dont know any other way how to center the panel with checkboxes then to use GridBagLayout and when i use this, i cannot draw anything to the frame"
I can't really tell what you're doing wrong without a complete example. I don't even see where you're trying to add the image. But don't try and draw on the frame. Draw on a JPanel instead.
Here is an example you may be able to gain some insight from.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
public class ImageByDrawing {
public ImageByDrawing() {
ImagePanel imagePanel = new ImagePanel();
imagePanel.setBorder(new TitledBorder("Drawn Image onto JPanel"));
JCheckBox germanBox = new JCheckBox("German");
germanBox.setOpaque(false);
JCheckBox englishBox = new JCheckBox("English");
englishBox.setOpaque(false);
JPanel boxPanel = new JPanel();
boxPanel.setBorder(new TitledBorder("JPanel with default FlowLayout"));
boxPanel.setOpaque(false);
boxPanel.add(germanBox);
boxPanel.add(englishBox);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(imagePanel, BorderLayout.CENTER);
centerPanel.add(boxPanel, BorderLayout.SOUTH);
centerPanel.setBorder(new TitledBorder("JPanel with BorderLayout"));
centerPanel.setOpaque(false);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.add(centerPanel);
mainPanel.setBorder(new TitledBorder("JPanel with GridBagLayout"));
mainPanel.setBackground(new Color(216,252,202));
JFrame frame = new JFrame();
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class ImagePanel extends JPanel {
BufferedImage img;
int dWidth;
int dHeight;
public ImagePanel() {
try {
img = ImageIO.read(getClass().getResource("/resources/stackblack.jpg"));
dWidth = img.getWidth();
dHeight = img.getHeight();
} catch (IOException ex) {
Logger.getLogger(ImageByDrawing.class.getName()).log(Level.SEVERE, null, ex);
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, img.getWidth(), img.getHeight(), this);
}
#Override
public Dimension getPreferredSize() {
return (img == null) ? new Dimension(300, 300) : new Dimension(dWidth, dHeight);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
new ImageByDrawing();
}
});
}
}
Also I don't know why you prefer to draw the image. The same can be easily done with a JLabel and ImageIcon
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
public class ImageByDrawing {
public ImageByDrawing() {
ImageIcon icon = new ImageIcon(getClass().getResource("/resources/stackblack.jpg"));
JLabel label = new JLabel(icon);
label.setBorder(new TitledBorder("JLabel with ImageIcon"));
JCheckBox germanBox = new JCheckBox("German");
germanBox.setOpaque(false);
JCheckBox englishBox = new JCheckBox("English");
englishBox.setOpaque(false);
JPanel boxPanel = new JPanel();
boxPanel.setBorder(new TitledBorder("JPanel with default FlowLayout"));
boxPanel.setOpaque(false);
boxPanel.add(germanBox);
boxPanel.add(englishBox);
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.add(label, BorderLayout.CENTER);
centerPanel.add(boxPanel, BorderLayout.SOUTH);
centerPanel.setBorder(new TitledBorder("JPanel with BorderLayout"));
centerPanel.setOpaque(false);
JPanel mainPanel = new JPanel(new GridBagLayout());
mainPanel.add(centerPanel);
mainPanel.setBorder(new TitledBorder("JPanel with GridBagLayout"));
mainPanel.setBackground(new Color(216, 252, 202));
JFrame frame = new JFrame();
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ImageByDrawing();
}
});
}
}
The last part of your question, as #Jere pointed out you can use setFocusPainted for the check box germanBox.setFocusPainted(false);

java Swing best way to place panels within frame

i have 3 panels, panel1 has 3 components(ADD, Delete, Edit) JButtons, panel2(scrollPane) has jtable and panel3 again as (5 JTextFields, 5JLabels). when I add all panels into frame panel3 components shows paritialy only means (4JTextFields) only visible within frame. for panels I used BorderLayout for frame.add(panel2,BorderLayout.SOUTH) , frame.add(panel3,BorderLayout.CENTER); panel1, panel2 shows all of components, but panel3 shows partially only. could you please suggest me precisely what layout should I use, for panels, and how to setsize for my frame to accomodate all panels(components)? clearly?
`
frame.add(topPanel, BorderLayout.NORTH);
frame.add(updatePanel, BorderLayout.SOUTH);
frame.add(middlePanel, BorderLayout.CENTER);
frame.setVisible(true);
frame.setSize(850, 500);
`
Try using Window#pack
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents. The resulting width and height of the window are
automatically enlarged if either of dimensions is less than the
minimum size as specified by the previous call to the setMinimumSize
method.
If the window and/or its owner are not displayable yet, both
of them are made displayable before calculating the preferred size.
The Window is validated after its size is being calculated.
Updated with example
Without a SSCCE (working example), it's impossible to fully diagnose your problem. Let me demonstrate...
So, based on your description, I can create this without any issues...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TestPack {
public static void main(String[] args) {
new TestPack();
}
public TestPack() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TopPanel(), BorderLayout.NORTH);
frame.add(new MiddlePanel(), BorderLayout.CENTER);
frame.add(new UpdatePanel(), BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TopPanel extends JPanel {
public TopPanel() {
setBackground(Color.red);
add(new JLabel("I'm on top"));
}
}
public class MiddlePanel extends JPanel {
public MiddlePanel() {
setLayout(new BorderLayout());
add(new JScrollPane(new JTable(new DefaultTableModel(new Object[]{"A", "B", "C"}, 5))));
}
}
public class UpdatePanel extends JPanel {
public UpdatePanel() {
for (int index = 0; index < 5; index++) {
add(new JLabel(Integer.toString(index)));
add(new JTextField(5));
}
add(new JButton("Button"));
}
}
}
But obviously, you're doing something different. Take the time to update your question with a working example, otherwise there's nothing more we can possible do

Border with equal sizes on all 4 sides of JTextpane

I am setting a createLineborder to my JTextPane. But the border lines are little different in right-end and bottom of JTextpane when compared to Left-end and top of TextPane. I searched in net and I found that it is the default behavior of lineborder. So can anyone please tell me that is there any border which gives equal lines sizes in all 4 sides?
Hi I cannot put my code as it is very huge. So just putting a sample code here.
JPanel panel;
JTextPane pane;
public BorderedTextPane() {
// TODO Auto-generated constructor stub
pane = new JTextPane();
panel = new JPanel(null);
JPanel innerPanel = new JPanel(null);
innerPanel.setBounds(50,50,300,400);
pane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
pane.setSize(new Dimension(innerPanel.getWidth(),innerPanel.getHeight()));
innerPanel.add(pane);
panel.add(innerPanel);
add(panel);
setVisible(true);
setSize(new Dimension(500,500));
setLocationRelativeTo(null);
}
This could be clearly seen if you zoom the textpane or when you save it on a file. Below image would explain it in better way. Compare the left and right lines.
I would say it has more to do with using null layouts...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
public class TestBorder {
public static void main(String[] args) {
new TestBorder();
}
public TestBorder() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new BorderLayout());
setBorder(new EmptyBorder(10, 10, 10, 10));
JTextPane pane = new JTextPane();
JPanel panel = new JPanel(new BorderLayout());
JPanel innerPanel = new JPanel(new BorderLayout());
pane.setBorder(BorderFactory.createLineBorder(Color.BLACK));
innerPanel.add(pane);
panel.add(innerPanel);
add(panel);
}
}
}
From the JComponent#setBorder() API:
Although technically you can set the border on any object that inherits from JComponent, the look and feel implementation of many standard Swing components doesn't work well with user-set borders. In general, when you want to set a border on a standard Swing component other than JPanel or JLabel, we recommend that you put the component in a JPanel and set the border on the JPanel.
Consult API setBorder method (new EmptyBorder ());
As well as using the variable JTextPane varible.setBorder (BorderFactory.createLineBorder (Color.xxx);

Width in box layout

here is piece of my code:
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
JPanel a = new JPanel();
a.setAlignmentX(Component.CENTER_ALIGNMENT);
a.setPreferredSize(new Dimension(100, 100));
a.setBorder(BorderFactory.createTitledBorder("aa"));
JPanel b = new JPanel();
b.setAlignmentX(Component.CENTER_ALIGNMENT);
b.setPreferredSize(new Dimension(50, 50));
b.setBorder(BorderFactory.createTitledBorder("bb"));
pane.add(a);
pane.add(b);
problem is with the width of second panel as you can see in image:
How can I fix it ?
because in flow layout it looks like I want:
As mentioned before, BoxLayout pays attention to a component's
requested minimum, preferred, and maximum sizes. While you are
fine-tuning the layout, you might need to adjust these sizes.¹
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class BoxLayoutDemo {
private static void createAndShowGUI(){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
JPanel a = new JPanel();
a.setAlignmentX(Component.CENTER_ALIGNMENT);
a.setPreferredSize(new Dimension(100, 100));
a.setMaximumSize(new Dimension(100, 100)); // set max = pref
a.setBorder(BorderFactory.createTitledBorder("aa"));
JPanel b = new JPanel();
b.setAlignmentX(Component.CENTER_ALIGNMENT);
b.setPreferredSize(new Dimension(50, 50));
b.setMaximumSize(new Dimension(50, 50)); // set max = pref
b.setBorder(BorderFactory.createTitledBorder("bb"));
frame.getContentPane().add(a);
frame.getContentPane().add(b);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
}
¹ How to Use BoxLayout: Specifying Component Sizes .

Categories