I'm trying to create a button and place it in a certain location, but for some reason it never goes in that specific location. I tried putting it a panel, using setBounds, using setLocation... but It doesn't seem to work...
I'm running this file in another file.
public class Inventory extends JPanel
{
private final static int frameWidth = 200;
private final static int frameHeight = 500;
private final static int screenLocationX = 100;
private final static int screenLocationY = 50;
private Panel panel;
private JFrame frame;
private JPanel jpanel;
public Inventory()
{
panel = new Panel();
frame = new JFrame();
JButton button = new JButton("Add Gem");
button.addActionListener(new Listener());
button.setPreferredSize(new Dimension(frameWidth,50));
// button.setLocation(0,400);
// button.setBounds(0,400,frameWidth,50);
panel.setVisible(true);
frame.setContentPane(panel);
frame.add(button);
frame.setVisible(true);
frame.setSize(frameWidth, frameHeight);
frame.setLocation(screenLocationX, screenLocationY);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
panel.addImage(new Gems());
}
}
}
Before adding panel to the frame use:
panel.setLayout(null); //setting the default settings of panel to null
and then use:
button.setBounds(300, 300, 300, 300); //bounding the button at specific location
this would work..
You need to turn the LayoutManager off
panel.setLayout(null);
JFrame by default uses a BorderLayout and, by default, components are added to the BorderLayout.CENTER position, unless otherwise specified
In this setup, the component will be placed on the centre of the frame and sized to fill it
Remember, each platform/OS renders content differently and these differences will change the amount of space required to display your components and all of this will effective the relationships between all the other components...
You consider changing the layout manager and using a combination of EmptyBorders and insets/padding to influence the location/size of your components. Try something like GridBagLayout or if your adventurous, checking out MigLayout
One of the first lessons you need to learn with GUI program (on just about any platform) is pixel perfect layouts are an illusion, there are too many variables which effect how content is rendered and how these can change the amount of space individual components will need in order to be displayed correctly...
Related
Code:
public class launcher implements ActionListener {
private static JFrame window;
private static JPanel panel;
private JButton createPassword;
private JButton seePassword;
public launcher() {
window = new JFrame();
panel = new JPanel();
window.setTitle("Password Vault");
window.setSize(400, 260);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setLocationRelativeTo(null);
window.setResizable(false);
window.setVisible(true);
window.getContentPane().add(panel); // Adds panel to JFrame
createPassword = new JButton("Create Password");
createPassword.setBounds(20, 100, 150, 100);
createPassword.addActionListener(this);
seePassword = new JButton("View Password");
seePassword.setLocation(20, 50);
seePassword.addActionListener(this);
panel.add(createPassword);
panel.add(seePassword);
}
public static void main(String[] args) {
new launcher();
}
Why can I not change the location of my JButtons? I have tried the setBounds and setLocation function but my buttons still stay on the top middle part of the JFrame window. I have also tried declaring my buttons inside the launcher() method and declaring them as a static variable.
You should NOT attempt to set the size/location of your buttons.
Swing was designed to be used with layout managers. The layout manager will set the size/location of the button based on the rules of the layout manager.
The default layout manager for a JPanel is the FlowLayout, which is why you see the button centered.
If you want to position the buttons differently, then you need to change the layout manager.
Read the section from the Swing tutorial on Layout Managers for more information and examples.
It looks like you want the buttons displayed vertically, so maybe a BoxLayout or GridLayout can be used depending on your exact requirement.
Other issues with your code:
Class names should start with an upper case character
There is no need to use static variables. That is not how the static keyword should be used
Components should be added to the frame BEFORE the frame is made visible.
You should be invoking pack() on the frame, BEFORE invoking setVisible(...) so the components can be displayed at their preferred size.
While you really shouldn't change the place of your components without a layout manager, there is a way. If you put this line of code into your code, it should work with setBounds:
window.setLayout(null);
I'm trying to create a GUI, and I want to place elements in certain places. I made the layout of my panel null, so I could do this. However, Nothing will appear when the panel is null. Here's the code:
public class OverView extends JFrame {
//height and width of screen
Toolkit tk = Toolkit.getDefaultToolkit();
int x = ((int) tk.getScreenSize().getWidth());//length of screen
int y = ((int) tk.getScreenSize().getHeight());//height
//components
private JLabel title;
private JLabel description;
private JPanel panel;
private ArrayList<JButton> farms;
//farm variables
public ArrayList<Farm> owned;
public OverView(ArrayList<Farm> owned) {
super("The Lolipop Farm - Overview");
setSize(700, 700);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(null);
//initialize variables
this.owned = owned;
panel = new JPanel();
panel.setLayout(null);
title = new JLabel("<html>Your Farms - The Lolipop Farm"
+ "<br> <font size=1000> <i> An Eph Production </i> </font></html>");
//set background color, color, and font of JComponents
title.setFont(new Font("serif", Font.BOLD, 25));
title.setBackground(Color.GRAY);
title.setOpaque(true);
//set size and location of the components
title.setSize(350, 120);
title.setLocation(x / 2, 600);
//add to panel
panel.add(title);
//add panel to the screen
add(panel);
}
}
Why isn't the panel showing anything when the layout's null?
As Overview is a Frame, I think you must call the method
setVisible(true);
according to https://docs.oracle.com/javase/tutorial/uiswing/layout/using.html in order to make it visible .
Now, if that doesn't work, I wonder if you have created an instance of the Overview class somewhere else in your code, or in the Main method. If you haven't, then there is no object that can show the panel inside of your class so your program won't show anything.
Your problem is with the code
setLayout(null);
This will set the layout of the JFrame to null since you are extending (inheriting it). You must have a layout for a JFrame although you can do without layout for JPanel. Just remove that line and it will be fine.
EDIT:
And of course you need to call setVisible(true) like the other guy said.
So, I have a tiny GUI program and I decided to use the BoxLayout to display the components from top to bottom. Everything works fine but I'm not able to change the height of my JButtons. I tried many things like setPreferredSize() but then i had the problem that the width isn't correct, as well. Using setMaximumSize() sets the width like i want to but the height still doensn't change. Maybe some of you could help me :) Thanks
public class SimpleSkinViewer extends JPanel implements ActionListener{
private final Dimension boxDimension = new Dimension(320, 320);
private final Dimension buttonDimension = new Dimension(320, 60);
private final Dimension spaceDimension = new Dimension(0, 5);
private JLabel imagebox;
private JButton loadButton;
private JButton changeButton;
private JButton downloadButton;
public SimpleSkinViewer() {
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
imagebox = new JLabel("");
imagebox.setIcon(new ImageIcon(loadImage("http://skins.minecraft.net/MinecraftSkins/AvarionDE.png")));
loadButton = new JButton("Load Skin");
changeButton = new JButton("Change Skin");
downloadButton = new JButton("Download");
//add listeners
loadButton.addActionListener(this);
changeButton.addActionListener(this);
downloadButton.addActionListener(this);
//dimensions
imagebox.setMaximumSize(boxDimension);
loadButton.setMaximumSize(buttonDimension);
changeButton.setMaximumSize(buttonDimension);
downloadButton.setMaximumSize(buttonDimension);
add(imagebox);
add(Box.createRigidArea(spaceDimension));
add(loadButton);
add(Box.createRigidArea(spaceDimension));
add(changeButton);
add(Box.createRigidArea(spaceDimension));
add(downloadButton);
}
#Override
public void actionPerformed(ActionEvent arg0) {
}
//and other stuff.....
public static void main (String[] args) {
JFrame frame = new JFrame("Avarion's Simple Skin Viewer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new SimpleSkinViewer());
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
}
You need Box.createVerticalGlue()
Change
add(changeButton);
add(Box.createRigidArea(spaceDimension));
with
add(changeButton);
add(Box.createVerticalGlue());
Then you can use .setPreferredSize(new Dimension(x,y)); and buttons will adapt to your layout
From the docs for BoxLayout
When a BoxLayout lays out components from top to bottom, it tries to
size each component at the component's preferred height.
For a top-to-bottom box layout, the preferred width of the container
is that of the maximum preferred width of the children. If the
container is forced to be wider than that, BoxLayout attempts to size
the width of each component to that of the container's width (minus
insets). If the maximum size of a component is smaller than the width
of the container, then X alignment comes into play.
So, you can set both the maximumSize and preferredSize to get the desired size.
loadButton.setMaximumSize(buttonDimension);
loadButton.setPreferredSize(buttonDimension);
My JFrame Consists of three main parts a banner at top scrollpane containing a JTextArea center and a JTextField at the bottom. When I re-size the frame I adjust the columns and rows in my JTextArea. When making the frame larger the JTextArea expands visually but removes the scroll-bar. Then if I make the frame smaller the JTextArea stays the same size. This Is where I attempt to re-size my JTextArea.
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
Why would the ScrollPane not re adjust to the change in size of the TextField.
The Rest of the code is below in case it is needed.
public class window extends JFrame
{
private static JFrame frame = new JFrame("Lillian");
private static JButton inputButton = new JButton("Send");
private static JTextField editTextArea = new JTextField(46);
private static JTextArea uneditTextArea = new JTextArea(26,50);
private static JPanel logoPanel = new JPanel();//Input text window
private static JPanel itextPanel = new JPanel();//Input text window
private static JPanel submitPanel = new JPanel();//Submit Button
private static JPanel bottom = new JPanel();//will contain scrollpane
private static JPanel middle = new JPanel();//willcontain itextpanel & submitbutton
private static JPanel otextPanel = new JPanel();//Text Output
public static void runWindow()
{
ImageIcon logo = new ImageIcon("Lillian_resize.png");//banner
ImageIcon icon = new ImageIcon("Lillian_icon.png");//application icon
frame.setIconImage(icon.getImage());
frame.setSize(660,640);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
logoPanel.setSize(10,10);
JLabel logoLabel = new JLabel(logo);
final JScrollPane scrollPane = new JScrollPane(otextPanel);//adds text to panel will scrollbar
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);//scrollbar only apears when more text than screen
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);//scrollbar never apears
scrollPane.setBorder(BorderFactory.createEmptyBorder());
logoPanel.add(logoLabel);
submitPanel.add(inputButton);
itextPanel.add(editTextArea);
otextPanel.add(uneditTextArea);
frame.getContentPane().add(logoPanel,"North");
frame.getContentPane().add(middle);
frame.getContentPane().add(bottom,"South");
middle.add(scrollPane,"North");//adds panels to outer panel
bottom.add(itextPanel, "West");
bottom.add(submitPanel, "East");
uneditTextArea.setLineWrap(true);
uneditTextArea.setWrapStyleWord(true);
uneditTextArea.setEditable(false);
uneditTextArea.setCaretPosition(uneditTextArea.getDocument().getLength());
frame.revalidate();//refreshes screen
//---------------wait for action------------
frame.addComponentListener(new ComponentAdapter() {//Waits for window to be resized by user
public void componentResized(ComponentEvent e) {
uneditTextArea.setRows(((int)((frame.getHeight()-140)/18.8)));//sets Textarea size based on window size
uneditTextArea.setColumns(((int)((frame.getWidth()-100)/10.8)));
frame.revalidate();//refreshes screen
}
});
}
}
There should be no need to use a ComponentListener to resize components. That is the job of the layout managers that you use to dynamically resize the components.
You should not be adding the text area to a JPanel first. Instead when using text areas you would generally add the text area directly to the viewport of a JScrollPane by using code like:
JScrollPane scrollPane = new JScrollPane( textArea );
Then you add the scrollpane to the frame with code like:
frame.add(scrollPane, BorderLayout.CENTER);
As you have noticed you should also NOT use hardcoded literals like "Center". Instead use the variables provided by the layout manager. Since you are using a BorderLayout, use the variables defined in the BorderLayout class.
Also, you should NOT be using static variable to create your GUI. I suggest you read the section from the Swing tutorial on Layout Manager. The tutorial will give you more information and the example code will show you how to better structure your program so that you don't need to use static variables.
I have 2 classes,
My main class creates a frame and I want another class to add content to it. A bit of reading arroudn told me I should use components to do this however when I run my code the frame is empty.
public static void main(String[] args)
{
// create frame
JFrame frame = new JFrame();
final int FRAME_WIDTH = 800;
final int FRAME_HEIGHT = 600;
// set frame attributes
frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
frame.setTitle("My Frame");
frame.setVisible(true);
Component1 Com = new Component1();
Component add = frame.add(Com);
}
My Component class creates a JLabel
public class Component1 extends JComponent {
public void paintComponent()
{
JLabel label = new JLabel("<html>Some Text</html>");
}
}
I don't get any compile errors, however I dont get any text in my JFrame.
Can anyone explain what I'm doing wrong?
Chris
You need to add the JLabel. Also better to extend JPanel instead of JComponent as it has a default layout manager and will make any added components appear without the need to set component sizes. paintComponent is used for custom painting BTW.
public class Component1 extends JPanel {
Component1() {
JLabel label = new JLabel("<html>Some Text</html>");
add(label);
}
}
No need to create a new Component. Just call frame.getContentPane().add(label). And initialize your label before this.