I'm trying to make a JFrame with a usable content area of exactly 500x500. If I do this...
public MyFrame() {
super("Hello, world!");
setSize(500,500);
}
... I get a window whose full size is 500x500, including the title bar, etc., where I really need a window whose size is something like 504x520 to account for the window border and titlebar. How can I achieve this?
you may try couple of things:
1 - a hack:
public MyFrame(){
JFrame temp = new JFrame;
temp.pack();
Insets insets = temp.getInsets();
temp = null;
this.setSize(new Dimension(insets.left + insets.right + 500,
insets.top + insets.bottom + 500));
this.setVisible(true);
this.setResizable(false);
}
2- or
Add a JPanel to the frame's content pane and
Just set the preferred/minimum size
of the JPanel to 500X500, call pack()
2- is more portable
Simply use:
public MyFrame() {
this.getContentPane().setPreferredSize(new Dimension(500, 500));
this.pack();
}
There's no need for a JPanel to be in there, if you just want to set the frame's size.
Never mind, I figured it out:
public MyFrame() {
super("Hello, world!");
myJPanel.setPreferredSize(new Dimension(500,500));
add(myJPanel);
pack();
}
Related
This is for Tetris. The glass (blue) is left, and the controls (red panel) are situated in the right. In other words, now I would like just to have a frame divided into two parts: left (wider) part is blue, right part is red. Nothing more. But I seem to fail to do this.
So, my logic is: let the frame have FlowLayout. Then I add two panels which means that they are expected to be put in a row.
I prepared this:
public class GlassView extends JFrame{
public GlassView(){
this.setSize(600, 750);
this.setVisible(true);
this.setLayout(new FlowLayout());
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel glass = new JPanel();
glass.setLayout(new BoxLayout(glass, BoxLayout.Y_AXIS));
glass.setSize(450, 750);
glass.setBackground(Color.BLUE);
glass.setVisible(true);
this.add(glass);
JPanel controls = new JPanel();
controls.setLayout(new BoxLayout(controls, BoxLayout.Y_AXIS));
controls.setSize(150, 750);
controls.setBackground(Color.RED);
controls.setVisible(true);
this.add(controls);
}
}
But only a gray frame is visible on the screen. Could you help me understand why?
As Amir said you want to use a JSplitPane for this. I have added this in your code. Have a look at this.
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
GlassView view = new GlassView();
}
private static class GlassView extends JFrame {
private int width = 600;
private int height = 750;
public GlassView() {
this.setSize(width, height);
this.setVisible(true);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JPanel glass = new JPanel();
glass.setSize(450, 750);
glass.setBackground(Color.BLUE);
glass.setVisible(true);
JPanel controls = new JPanel();
controls.setSize(150, 750);
controls.setBackground(Color.RED);
controls.setVisible(true);
JSplitPane splitPane = new JSplitPane();
splitPane.setSize(width, height);
splitPane.setDividerSize(0);
splitPane.setDividerLocation(150);
splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setLeftComponent(controls);
splitPane.setRightComponent(glass);
this.add(splitPane);
}
}
How to divide a frame into two parts
...
I would like just to have a frame divided into two parts: left (wider) part is blue, right part is red.
You want to use is a SplitPane.
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);
Currently working on a project and I need to add a panel I've made to a scrollpane or a table dynamically. The scrollpane should start out empty and add the panels.
The GuiConstructor is where i make the window.
My problem is that if I don't comment out the setSize in the GuiConstructor, the window starts out very small.
Secondly, when i press the add button, it doesn't add the panels.
public GuiConstructor(){
super(APPLICATION_NAME);
setLayout(new BorderLayout());
LoopControlWindow loopwin = new LoopControlWindow(connect);
add(loopwin , BorderLayout.NORTH);
pack();
setLocationRelativeTo(null);
setResizable(false);
setVisible(true);
//this.setSize(500, 500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public class LoopControlWindow extends JPanel {
IConnector connect;
public LoopControlWindow(IConnector connect) {
super(new BorderLayout());
this.connect = connect;
initPane();
}
private void initPane() {
JPanel panel = new JPanel(new GridLayout(3,1));
FolderSearchComp fsc = new FolderSearchComp(connect);
JScrollPane scrollPane = new JScrollPane();
JButton button = new JButton("Add");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new FolderSearchComp(connect));
scrollPane.getViewport().setView(panel);
}
});
scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setViewportBorder(new LineBorder(Color.BLACK));
add(scrollPane, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
}
This is typical of this style of GUI app. You need to tell the layout manager how big to make the Window initialy without using setSize(). The way to do this is to override getPreferredSize() to return a default size. In your case:
public LoopControlWindow extends JPanel {
private Dimension size;
public LoopControlWindow() {
Preferences prefs = Preferences.userNodeForPackge("your.java.package");
size = new Dimension(prefs.getInt("width", 800), prefs.getInt("height", 600));
}
public Dimension getPreferredSize() {
return size;
}
}
By doing it this way you can store the user preferences for the window dimensions but also provide sensible defaults to start.
You should also make sure that this JPanel is your main panel and is added to the JFrame at BorderLayout.CENTER to ensure that your window gets drawn properly. All other panels should be somewhere inside this one.
Once you have this set up calling pack() will work correctly.
For your first problem, you need to specify a size for the initial JFrame(). One way is to call setSize as you are doing. Another is to override getPreferredSize() to return the default size. And one other option is to find the size of the user's monitor and set the JFrame to be a percentage of that size. That way you can ensure your window always fits on your user's screen.
int height = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().
getBounds().height;
height = (int) (height * .85);
int width = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration().
getBounds().width;
width = (int) (width * .85);
frame.setSize(width, height);
Second, you need to call revalidate() and repaint() anytime you add or remove from a layout in order to see the changes.
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
panel.add(new FolderSearchComp(connect));
scrollPane.getViewport().setView(panel);
revalidate();
repaint();
}
});
One note on border layout. The components in it will not resize with your JFrame. Whatever component that is placed in BorderLayout.CENTER will, however. That component will grow to fill all extra space as the JFrame grows. It will also be the component that shrinks when the JFrame windows gets smaller.
Is it possible to have some extra space around the edges of a JFrame that uses AbsoluteLayout? When I have a button as the downwardsmost component on the JFrame, it gets positioned right up against the bottom edge of the JFrame window, and it looks bad. I would like to know if there's a way to add a little extra space between components and the edge of the JFrame while using AbsoluteLayout.
Suggestions:
When you add a component to a JFrame, you're actually adding it to the JFrame's contentPane. To give the contentPane a "buffer" border, consider giving it an EmptyBorder(...) with the parameters being int constants for the amount of border desired around the component.
Avoid using "absolute" layouts for anything, and especially for placing components at easy to place locations for the layout managers, such as at the bottom of the GUI.
For example, note in the GUI created in the code below how the center and bottom JPanel's don't go out to the edge of the GUI because of the empty border:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
public class ButtonAtBottom {
private static void createAndShowGui() {
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton("Bottom Button"));
bottomPanel.setBorder(BorderFactory.createTitledBorder("Bottom Panel"));
JPanel centerPanel = new JPanel();
centerPanel.setBorder(BorderFactory.createTitledBorder("Center Panel"));
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
// **** here I add the border to the mainPanel which I'll
// make into the contentPane
int eb = 25;
mainPanel.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
// don't set the preferredSize per Kleopatra, but am doing it
// here simply to make code shorter for this sscce
mainPanel.setPreferredSize(new Dimension(500, 400));
JFrame frame = new JFrame("ButtonAtBottom");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You can use Box.createRigidArea(dimensions) to create an empty space that you can add below the button.
Set an empty border on your content panel where SIZE is the amount of padding you want.
JFrame frame = new JFrame();
JPanel panel = new JPanel(null);
panel.setBorder(BorderFactory.createEmptyBorder(SIZE,SIZE,SIZE,SIZE);
frame.setContentPane(panel);
//The rest
The arguments are for top, left, bottom and right padding so if you want different paddings on each edge, you can set it accordingly.