I am playing around with Java GUIs, and I came across JLabel.setVerticalAlignment. I have set something up so that curlLeft and curlRight would go to the corners. However, it does not seem to have ny effect. Why is that so?
private void prepareGUI() throws IOException {
mainFrame = new JFrame("Holy Bible");
mainFrame.setSize(700, 500);
mainFrame.setLayout(new GridLayout(1, 2));
mainFrame.setLocationRelativeTo(null);
mainFrame.setIconImage(new ImageIcon(getClass().getResource("/assets/bible/textures/icon.png")).getImage());
mainFrame.getContentPane().setBackground(Color.WHITE);
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent) {
System.exit(0);
}
});
mainFrame.addKeyListener(this);
leftPanel = new JPanel();
leftPanel.setBackground(Color.WHITE);
leftPanel.setLayout(new FlowLayout());
rightPanel = new JPanel();
rightPanel.setBackground(Color.WHITE);
rightPanel.setLayout(new FlowLayout());
leftLabel = new JLabel("", JLabel.CENTER);
leftLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
leftPanel.add(leftLabel);
rightLabel = new JLabel("", JLabel.CENTER);
rightLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 12));
rightPanel.add(rightLabel);
leftCurl = new JLabel();
leftCurl.setHorizontalAlignment(JLabel.LEFT);
leftCurl.setVerticalAlignment(JLabel.BOTTOM);
leftCurl.setIcon(new ImageIcon(getClass().getResource("/assets/bible/textures/curlleft15.png")));
leftPanel.add(leftCurl);
rightCurl = new JLabel();
rightCurl.setHorizontalAlignment(JLabel.RIGHT);
rightCurl.setVerticalAlignment(JLabel.BOTTOM);
rightCurl.setIcon(new ImageIcon(getClass().getResource("/assets/bible/textures/curlright15.png")));
rightPanel.add(rightCurl, BorderLayout.SOUTH);
mainFrame.add(leftPanel);
mainFrame.add(rightPanel);
mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); // Maximizes frame
mainFrame.setUndecorated(fullScreen);
mainFrame.setVisible(true);
}
All the variables needed are initialized at class level.
Your JLabels are not going to the corners because you are adding them to JPanels that have a FLowLayout. With FlowLayout your components don't occupy the 100% of the space of the JPanel, they only occupy the necessary.
I changed the 2 FlowLayouts to GridLayouts and now I can see the different orientations.
(Also, as your objective is learning how this works, I recommend you set a border on each component so you can see where their bounds are. This is quite good for understanding Swing's layout management).
Related
I want to align Labels and a Panel (containing Buttons) to the left inside a vertical BoxLayout.
As long as I don't add the panel to the BoxLayout everything is aligned to the left perfectly, but adding it screws everything up.
import javax.swing.*;
import java.awt.*;
public class BoxLayoutDemo{
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JPanel five = new JPanel();
JButton plus = new JButton("+");
JButton minus = new JButton("-");
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
Font testFont = new Font("Arial", Font.BOLD, 20);
JLabel label1 = new JLabel("Label1");
label1.setFont(testFont);
JLabel label2 = new JLabel("Label2");
label2.setFont(testFont);
five.setLayout(new BoxLayout(five, BoxLayout.X_AXIS));
plus.setMinimumSize(new Dimension(30, 30));
plus.setMaximumSize(new Dimension(30, 30));
minus.setMinimumSize(new Dimension(30, 30));
minus.setMaximumSize(new Dimension(30, 30));
five.add(plus);
five.add(minus);
panel.add(label1);
panel.add(five);
panel.add(label2);
panel.setOpaque(true);
panel.setBackground(Color.red);
frame.setMinimumSize(new Dimension(200, 200));
frame.getContentPane().add(panel, BorderLayout.EAST);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Your components need to have the same "x alignment":
label1.setAlignmentX(Component.LEFT_ALIGNMENT);
label2.setAlignmentX(Component.LEFT_ALIGNMENT);
five.setAlignmentX(Component.LEFT_ALIGNMENT);
Read the section from the Swing tutorial on Fixing Alignment Problems for more information.
You can use invisible components as fillers.
private static Box leftAlignedInHorizontalBox(Component component) {
Box box = Box.createHorizontalBox();
box.add(component);
box.add(Box.createHorizontalGlue());
return box;
}
and then:
panel.add(leftAlignedInHorizontalBox(label1));
I'm using the BeautyEye Laf for a Java Swing application.
I'm setting a JTextField inside a JPopupMenu. The JTextField appears disabled no matter what I do. The code is a bit complicated but I've made this snippet that's easily testable
public static void main(String[] s)
throws Exception
{
BeautyEyeLNFHelper.frameBorderStyle = BeautyEyeLNFHelper.FrameBorderStyle.generalNoTranslucencyShadow;
org.jb2011.lnf.beautyeye.BeautyEyeLNFHelper.launchBeautyEyeLNF();
final JPopupMenu popupTable = new JPopupMenu();
// find panel
JLabel findLabel = new JLabel("Filter for:");
findLabel.setPreferredSize(new Dimension(60, 20));
final JTextField findTextField = new JTextField();
findTextField.setColumns(10);
final JPanel container = new JPanel();
container.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
container.add(findLabel);
container.add(findTextField);
popupTable.add(container);
JButton button = new JButton("Action");
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
buttonPanel.add(button);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(popupTable, BorderLayout.CENTER);
panel.add(buttonPanel, BorderLayout.SOUTH);
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(900, 800);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setVisible(true);
button.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
int x = (frame.getWidth() / 2);
int y = (frame.getHeight() / 2);
popupTable.show(frame, x, y);
}
}
);
}
If I remove the LaF (comment the first two lines) everything works as expected. The JTextField is editable. I'm asking here first in hope that I'm doing something wrong. If this proves to be a bug I will post this as an issue on Github.
In the end it was a minor change in the library. From the author:
You can find class
org.jb2011.lnf.beautyeye.ch7_popup.TranslucentPopupFactory source code
at line 416, change "setFocusableWindowState(false);" to
"setFocusableWindowState(true);" or just delete this line.
So I'm trying to create a gui, I've tinkered with gui's before in java but I'm still new to them. So my issued here is that my JLabels (butLabel & cbLabel) are filled with buttons and checkboxes. Sadly my JFrame will only show whichever is set to the BorderLayout.CENTER. NORTH & SOUTH don't ever show, even if I only set the butLabel to SOUTH and don't even use the cbLabel. What am I overlooking?? It's much appreciated, thanks!
public class mainWindow
{
JFrame frame = new JFrame("Main Window");
JLabel butLabel = new JLabel();
JLabel cbLabel = new JLabel();
JButton showBut = new JButton("Show");
JButton exitBut = new JButton("Exit");
JButton addBut = new JButton("Add");
JButton remBut = new JButton("Remove");
JCheckBox aCB = new JCheckBox("Airplane");
JCheckBox bCB = new JCheckBox("Boat");
JCheckBox cCB = new JCheckBox("Clock");
public mainWindow()
{
frame.setLayout(new BorderLayout()); //I know this is set by default to BorderLayout but I just did it when I was out of options to try.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(360, 480));
butLabel.setLayout(new GridLayout(1,4));
cbLabel.setLayout(new GridLayout(2, 2));
butLabel.add(showBut);
butLabel.add(exitBut);
butLabel.add(addBut);
butLabel.add(remBut);
cbLabel.add(aCB);
cbLabel.add(bCB);
cbLabel.add(cCB);
frame.add(butLabel, BorderLayout.CENTER);
frame.add(cbLabel, BorderLayout.NORTH);
}
public void setVisible()
{
butLabel.setVisible(true);//Didn't think I needed butLabel.setVisible or the cbLabel.setVisible but
cbLabel.setVisible(true);//again I was trying things that I thought might make sense.
frame.setVisible(true);
}
}
do not use Label for grouping elements, use JPanel instead
I have tried replace all
Label
with
Panel
it works
I tried to do this from stackoverflow:
adding multiple jPanels to jFrame
But that didn't seem to work out like in the example, could anyone tell me what im doing wrong?
Im trying to add multiple JPanels with each their own sizes to the JFrame. I was also hoping it was possible to give each JPanel specific sizes and ability to put them on the exact spot i want.
Picture of what i try to make:
This is my code so far:
public ReserveringenGUI(ReserveringController controller) {
this.controller = new ReserveringController();
makeFrame();
}
public void makeFrame() {
JFrame frame1 = new JFrame();
frame1.setTitle("Reserveringen");
frame1.setSize(800, 500);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
JPanel willekeurigPanel = new JPanel();
willekeurigPanel.setSize(400, 500);
willekeurigPanel.setBackground(Color.YELLOW);
willekeurigPanel.setVisible(true);
JPanel overzichtPanel = new JPanel();
overzichtPanel.setSize(400, 500);
overzichtPanel.setBackground(Color.red);
overzichtPanel.setVisible(true);
DateFormat format = new SimpleDateFormat("dd-MM-yyyy");
DateFormatter df = new DateFormatter(format);
JFormattedTextField dateBeginField = new JFormattedTextField(df);
dateBeginField.setPreferredSize(new Dimension(250, 20));
dateBeginField.setValue(new Date());
JFormattedTextField dateEndField = new JFormattedTextField(df);
dateEndField.setPreferredSize(new Dimension(250, 20));
dateEndField.setValue(new Date());
JTextField klantnummer = new JTextField();
klantnummer.setPreferredSize(new Dimension(250, 20));
JTextField artikelnummer = new JTextField();
artikelnummer.setPreferredSize(new Dimension(250, 20));
JLabel dateBeginLabel = new JLabel("Begin Datum ");
JLabel dateEndLabel = new JLabel("Eind datum: ");
JLabel klantID = new JLabel("Klant nummer: ");
JLabel artikelID = new JLabel("Artikel nummer: ");
JButton voegReserveringToe = new JButton("Voeg toe");
voegReserveringToe.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
voegReserveringToeActionPerformed(evt);
}
});
willekeurigPanel.add(dateBeginLabel);
willekeurigPanel.add(dateBeginField);
willekeurigPanel.add(dateEndLabel);
willekeurigPanel.add(dateEndField);
willekeurigPanel.add(klantID);
willekeurigPanel.add(klantnummer);
willekeurigPanel.add(artikelID);
willekeurigPanel.add(artikelnummer);
willekeurigPanel.add(voegReserveringToe);
container.add(willekeurigPanel);
container.add(overzichtPanel);
frame1.add(container);
frame1.setVisible(true);
}
As discussed here, don't set the size and position of components arbitrarily. Instead, let the layout do the work, nesting as required. Use the GroupLayout shown here for the labeled input fields. Add each to the CENTER of a panel having BorderLayout, with a button in the SOUTH on the left. Finally, add both panels to an enclosing panel having GridLayout(1, 0).
I guess this is a simple question... basically it's about layout considerations. So let consider the code below, I get this:
.
public class TestCode_Web {
public static void main(String[] args) {
JFrame window = new JFrame("Test");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(200, 300);
// Inner panel ---------------------------------------------------------
JPanel innerPanel = new JPanel(new BorderLayout());
innerPanel.setBackground(new Color(250, 250, 200));
window.add(innerPanel);
// Northern panel ------------------------------------------------------
JPanel panelN = new JPanel(new BorderLayout());
JLabel labelN = new JLabel("Label");
panelN.add(labelN, BorderLayout.WEST);
panelN.setBackground(new Color(200, 250, 250));
innerPanel.add(panelN, BorderLayout.NORTH);
// Center panel --------------------------------------------------------
JPanel panelC = new JPanel();
panelC.setBackground(new Color(250, 200, 250));
JPanel panelCheckBoxes = new JPanel(new GridLayout(0, 1));
final JCheckBox c1 = new JCheckBox("C1");
final JCheckBox c2 = new JCheckBox("C2");
final JCheckBox c3 = new JCheckBox("C3");
panelCheckBoxes.add(c1);
panelCheckBoxes.add(c2);
panelCheckBoxes.add(c3);
int width = panelCheckBoxes.getPreferredSize().width;
int height = panelCheckBoxes.getPreferredSize().height;
panelCheckBoxes.setPreferredSize(new Dimension(width, height));
panelC.add(panelCheckBoxes);
innerPanel.add(panelC, BorderLayout.CENTER);
// Southern panel --------------------------------------------------------
JPanel panelS = new JPanel(new BorderLayout());
JLabel labelS = new JLabel(String.valueOf(width) + "/" + String.valueOf(height));
panelS.add(labelS, BorderLayout.WEST);
panelS.setBackground(new Color(250, 250, 200));
innerPanel.add(panelS, BorderLayout.SOUTH);
// ...
window.setVisible(true);
}
}
What I would like is to have this:
How could I achieve that ? I guesss there are several ways, I'm waiting for your diverse proposals...
One way to do this would be to overwrite the getPreferredSize() method of panelCheckBoxes to return panelC's width. This way, panelCheckBoxes' size will automatically adapt to the width of panelC.
final JPanel panelC = new JPanel();
// [...]
JPanel panelCheckBoxes = new JPanel(new GridLayout(0, 1)) {
public Dimension getPreferredSize() {
return new Dimension(panelC.getWidth(),
super.getPreferredSize().height);
}
};
For accessing panelC inside the anonymous inner class, it has to be final (i.e., after initialization, the panelC variable can not be assigned a new value, which is no problem in your case).
Just setting the preferredSize at that point in the constructor will not work, since (1) the size is not known yet, and (2) it might change when the window is resized. You could, however, use setPreferredSize after the call to window.setVisible(true);, when panelC got a size:
// after window.setVisible(true);
panelCheckBoxes.setPreferredSize(new Dimension(panelC.getWidth(),
panelCheckBoxes.getHeight()));
However, note that this way panelCheckBoxes still won't resize when you resize the window.
If you just want the checkboxes to be aligned to the left (but not necessarily stretch over the whole width), a simpler way would be to put panelC into the WEST container of the BorderLayout. Assuming that the colors are only for debugging and in the end everything will be the same color, you won't see a difference.
Finally, for more complex layouts you might want to check out GridBadLayout. It takes some getting used to, but once mastered, it's worth the effort.