With setLayout(null), I can tell my components to be at e.g. x 5 and y 60. However, this references to the window's x and y position, borders included.
Can I, somehow, tell my components that 0,0 is contentPane's upper left (visible) corner?
This is especially annoying since different OS have different sized window borders.
Code initialising the JFrame:
JFrameAdd addFrame;
addFrame = new JFrameAdd();
addFrame.setVisible(true);
addFrame.setTitle("Vokabeltrainer");
addFrame.setResizable(false);
addFrame.setLocationRelativeTo(null);
addFrame.setBounds(100, 100, 825, 585);
addFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
inside JFrameAdd.java:
JButton btnNewButton = new JButton(new ImageIcon(settingsIcon));
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFrameGenerated.settingsFrame.setVisible(true);
}
});
btnNewButton.setBounds(0, 510, 36, 36);
contentPane.add(btnNewButton);
All code is here: https://github.com/MisterSkilly/Vokabeltrainer/tree/LoadSave/Latein%20asterisk/src and yes I know I shouldn't run two JFrames simultaneously, but changing that messed things up and I don't have the time to change that ATM.
However, this references to the window's x and y position, borders included
No, it references the content pane, which does not include the titlebar and borders.
Can I somehow tell my components that 0,0 is contentPane's upper left (visible) corner?
This is the default behaviour.
If you believe your application is behaving differently then post your SSCCE that demonstrates the problem.
The general rule is DON'T use a null layout. Let the layout manager worry about positioning the components.
Related
I'm pretty new to GUI and Java as a whole so I hope that I can explain this well enough and understand people's answers.
For a school project, I need to put a bunch of stuff on some rectangles but I'm having issues even adding one rectangle properly.
From researching online, this is what I have (the JPanel and GridBagConstraints are just there to show what I'd like to use):
public class GUI extends JPanel
{
public static void main (String [] args)
{
GUI g = new GUI();
JFrame window = new JFrame("Java Window");
window.setSize(1280, 960);
window.add(g);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel layout = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
}
#Override
public void paintComponent(Graphics g)
{
Color boxColour = new Color(194, 190, 190);
super.paintComponent(g);
g.setColor(boxColour);
g.fillRect(10, 10, 100, 100);
}
}
So right now, the rectangle appears in the window. But how can I add constraints to it? Is that possible? I would think that I should use JPanel to keep everything more organized since there will be many components so I tried adding this:
layout.add(g);
window.add(layout);
window.setVisible(true);
However, the rectangle no longer appeared. What am I doing wrong and how can I fix it and add constraints to my shapes? Thanks!
In your first scenario, the default layout manager of the frame is the BorderLayout and you are adding your "g" panel to the BorderLayout.CENTER. So based on the rules of the BorderLayout your "g" panel will take up all the space available in the frame. So you have plenty of space to paint your rectangle.
However, in your second scenario, your "layout" panel is using the default layout manager of a JPanel which is a FlowLayout which respects the preferred size of any component added to it.
The preferred size of the "g" panel is 10 x 10. So, when you add the "g" panel to the "layout" panel there is nothing to see because all you custom painting is done outside the bounds of the panel.
You need to override the getPreferredSize() method of your GUI panel to return a preferred size of (120, 120) so you can see your rectangle painted with a 10 pixel border around all the edges.
Read the section from the Swing tutorial on Custom Painting for more information and working examples demonstrating how to override the `getPreferredSize() method.
You will also need to read the Swing tutorial on How to Use GridBagLayout for example of using the constraints to add multiple components.
I want to set a specific layout for this frame, for 'accuracy, I would like the frame to be displayed in the center of the screen, I tried to enter the GridLayout (x, y), with specific coordinates, but it gives me warning in eclipse the only thing that i can do is to set the null layout,as below.
class Login extends JFrame {
/**
*
*/
setTitle("Title");
setLayout(null);
.
.
.
First, a warning shouldn't forbid you from compiling in most cases.
Second, you're misusing the constructor. Read the GridLayout docs - http://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html
If you want the frame to be displayed at the center of the screen, use setLocationRelativeTo(null);
GridLayout is not used to enter coordinates in terms of pixels but in terms of the grids you have created. If you want accurate positioning in pixels, set the layout to null, and then use setBounds() on any GUI component you wish.
For example:
JLabel aLabel = new JLabel("Title");
aLabel.setBounds(50, 50, 30, 10); //x, y, width, height
have you tried the "setLocationRelativeTo(null);"? this should center the frame
http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setLocationRelativeTo%28java.awt.Component%29
This question has been asked a lot but everywhere the answers fall short. I can get a JFrame to display a background image just fine by extending JPanel and overriding paintComponent, like so:
class BackgroundPanel extends JPanel {
private ImageIcon imageIcon;
public BackgroundPanel() {
this.imageIcon = Icons.getIcon("foo");
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(imageIcon.getImage(), 0,0,imageIcon.getIconWidth(),imageIcon.getIconHeight(),this);
}
}
But now, how do you add a component on top of that background?
When I go
JFrame w = new JFrame() ;
Container cp = w.getContentPane();
cp.setLayout(null);
BackgroundPanel bg = new BackgroundPanel();
cp.add(bg);
JPanel b = new JPanel();
b.setSize(new Dimension(30, 40));
b.setBackground(Color.red);
cp.add(b);
w.pack()
w.setVisible(true)
It shows the little red square (or any other component) and not the background, but when I remove cp.setLayout(null);, the background shows up but not my other component. I'm guessing this has something to do with the paintComponent not being called by the null LayoutManager, but I'm not at all familiar with how LayoutManagers work (this is a project for college and the assignment specifically says not to use a LayoutManager).
When i make the image the background has to display null (and so, transparant (??)) the red square shows up so it might be that the background is actually above my other components.
Does anyone anyone have any ideas?
Thanks
When using null layout (and you almost never should) you have to supply a bounds for every component, otherwise it defaults to (0 x,0 y,0 width,0 height) and the component won't display.
BackgroundPanel bg = new BackgroundPanel();
cp.add(bg);
isn't supplying a bounds. You'll need to do something like:
BackgroundPanel bg = new BackgroundPanel();
bg.setBounds(100, 100, 100, 100);
cp.add(bg);
Which would make bg size 100 x 100 and place it at 100 x, 100 y on the frame.
Look in the documentation on the Root Pane for all the information you need. Note the availability of the layered pane and the glass pane as well as the content pane.
By default all components have a 0 size. Just because you do some painting on a component doesn't give the component a size. You are still responsible for setting the size. That is why you should always use a layout manager. It looks after all this size stuff for you so you don't have to worry.
I don't know why newbies always think they can't use a layout manager. Yes it takes a couple of more minutes to learn, but it saves you a lot of grief in the long run.
Background Panel shows a couple of approaches. Again they both assume you use a layout manager, so you may need to set the size manually.
I'm creating an applet and having problems with the positioning as size of my buttons. I've added two buttons, but the "OK" button seems to position and size itself correctly, but the "CLEAR" button fills the entire applet area behind the "OK" button. Any suggestions as to what is the problem?
#Override
public void init()
{
super.init();
setSize(J_WIDTH, J_HEIGHT);
setLayout(new BorderLayout());
btn_OK = new Button("OK");
btn_CLEAR = new Button("CLEAR");
btn_OK.setBounds(50, 450, 75, 50);
btn_CLEAR.setBounds(125, 50, 75, 50);
add(btn_OK);
add(btn_CLEAR);
btn_OK.addActionListener(this);
btn_CLEAR.addActionListener(this);
}
When using a BorderLayout, you should specify a location where you want to place the component. If you don't, the default is BorderLayout.CENTER. Also, each position can only contain one component. So when you call add(btn_OK), the OK button is added to the center of the panel. But then you replace it with the Clear button by calling add(btn_CLEAR);.
In addition, each position in the BorderLayout takes up a certain amount of space. The component at that position will stretch to fill that space. In particular, the CENTER takes up all remaining space not used by the other positions.
I think that BorderLayout is not what you want here. Check out the Visual Guide to Layout Managers for more information on each LayoutManager. You can also follow the rest of the tutorial trail for details about how to implement each of them.
You should also bookmark and familiarize yourself with the Java API docs. These are an essential tool for every Java programmer and will help you answer many questions on your own.
OK, several questions about the test code below... I don't have the full working program to post, but I'm hoping people know Swing well enough to take a stab at it. This is a JLabel inside of a JPanel(BoxLayout), and I'm working on the sizing of the label in the lower right.
What I get with the code as shown is a status box 300 width by 30 height. I have fiddled with the preferred size and the label minimum size, and it does not seem to behave in any rational way.
Why does the JPanel Preferred Size affect the height but not the
width? If I change the x dimension in setPreferredSize() to 0 or
500, it still comes out 300 from the label.
Why does the JLabel Minimum Size affect the width but not the
height? If I comment the setPreferredSize() call and increase the
label height to 30, nothing happens.
I started out with JPanel setMinimumSize (commented), but it no longer has any
effect - why does the JPanel require setPreferredSize()?
If I change the label text from "" to " ", this increases the height
of the label. Since the label is not controlling the height here,
why does this have any effect at all?
By the way, the createRigidArea() call is to force the separator to the right, rather than sticking to the left hand side of the screen. If there are any less kludgy ideas for this, I'd be grateful.
private JComponent makeStatusBarTest() {
JPanel statusPanel = new JPanel();
statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.LINE_AXIS));
statusPanel.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
// statusPanel.setMinimumSize(new Dimension(0, 30));
statusPanel.setPreferredSize(new Dimension(500, 30));
JLabel statusLabel = new JLabel();
Border emptyBorder = BorderFactory.createEmptyBorder(5, 10, 5, 10);
statusLabel.setBorder(emptyBorder);
statusLabel.setText("");
statusLabel.setMinimumSize(new Dimension(300, 20));
statusPanel.add(statusLabel);
statusPanel.add(new JSeparator(SwingConstants.VERTICAL));
statusPanel.add(Box.createRigidArea(new Dimension(5000,0)));
return statusPanel;
}
I can explain #1 and #2:
From the BoxLayout javadocs: "BoxLayout attempts to arrange components at their preferred widths (for horizontal layout) or heights (for vertical layout)."
In other words, BoxLayout uses the internal components (in your case, statusLabel) to decide the widths, but the JPanel itself (within reason) to decide the heights.
You can usually use Glue instead of RigidArea to move stuff around, but I agree that it takes some getting used to.
#4 is Swing being too efficient - if the JLabel is empty the text rectangle is 0x0. Ultimately determined in SwingUtilities.layoutCompoundLabelImpl().
I think #3 is because BoxLayout is trying to respect the preferred size of the internal components. Since setMinimumSize, arguably, overrides their preferred sizes.