I am creating a simple game using Java. I have created the game's menu using JFrame. I am having confusion about what layouts to be used to place the Menu Buttons(Start,High Scores,Instructions,Exit) at the center. I have an approach in mind that is :
Creating a grid layout of three columns and in the middle column adding a box layout(having the menu buttons) positioned at the center of this column.
Should I use this approach? if not then please tell me the solution.
Use a GridBagLayout
JButton startButton = new JButton("Start");
JButton scoreButton = new JButton("High Score");
JButton instructButton = new JButton("Instructions");
JButton exitButton = new JButton("Exit");
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = java.awt.gbc.HORIZONTAL;
gbc.insets = new java.awt.Insets(2, 2, 2, 2);
gbc.gridx = 0;
gbc.gridy = 0;
getContentPane().add(startButton, gbc);
gbc.gridy = 1;
getContentPane().add(scoreButton, gbc);
gbc.gridy = 2;
getContentPane().add(instructButton, gbc);
gbc.gridy = 3;
getContentPane().add(exitButton, gbc);
Madprogrammer is right, use a gridbaglayout. I myself am actually too lazy to fool around with layout managers so I use WindowBuilder for Eclipse SDK. Search for it on google. WindowBuilder has bi directional code generation (ie, it can parse swing code and then generate it from what you do in the gui), and its all drag and drop.
Related
I'm trying to align 3 items in a GridBagLayout, 2 of the items being on top and 1 item at bottom. Both Items should be the same Size. I have tried to achieve this with BorderLayout and GridBagLayout but no luck.
This is my attempt with GridBagLayout as you can see they are not properly aligned. This is what I tried to do.
Add first item
Set the x to 1
Add second item
Set the y to 1
Add the last item
I was hoping this would work because It doesn't make sense to me why this would not work, Here is the code for it.
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
JTextField oldPkg = new JTextField();
container.add(oldPkg, gbc);
gbc.gridx = 1;
JTextField newPkg = new JTextField();
gbc.gridy = 1;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
The result I want to achieve is
I have achieved it with FlowLayout but it doesn't resign packed when the frame is resized, and the bottom bar is a bit big.
How can I achieve this with GridBagLayout or any other layout so it remains the same on size changes?
Sometimes, you need to set back and try a different approach. Maybe starting with and piece of paper, where you can draw the layout and plot out the constraints.
This will lead you to understanding that apkPath needs to start at x of 0 and "span" two columns.
Currently apkPath is using the same x position as newPkg, you need to change it before using it again.
gbc.gridy = 1;
gbc.gridx = 0;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
Okay, but now it's the same size as oldPkg, we need to tell GridBagLayout we want to span multiple columns
gbc.gridy = 1;
gbc.gridx = 0;
gbc.gridwidth = 2;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
should now allow the textfield to flow over both columns
I might suggest having a look at How to Use GridBagLayout for more details
Slightly off topic:
Might I just suggest not bothering with 90% of the inbuilt layouts and just going with MigLayout.
There is a MigLayout core jar, and MigLayout swing jar. (Don't take the MigLayout SWT jar by mistake, and also don't use the SWT versions in the import statements).
I guess the licence is liberal. But, you can check whether it fits your needs.
http://www.miglayout.com/
(Just a happy user. Not affiliated)
This does a lot in just a few lines:
public class LayoutAnswer extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
LayoutAnswer window = new LayoutAnswer();
window.init();
window.pack();
window.setVisible(true);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
private JPanel panel = new JPanel( new MigLayout("insets 10","[300::, grow][400::, grow]","[100:150:200][100:150:200]") );
private JLabel lbl1 = new JLabel("One");
private JLabel lbl2 = new JLabel("Two");
private JLabel lbl3 = new JLabel("Three");
public void init() {
add(panel, BorderLayout.CENTER);
panel.add(lbl1, "");
panel.add(lbl2, "wrap");
panel.add(lbl3, "span 2");
}
}
I need some help in JInternalFrame within JPanel's Area.I have a JFrame which contains
JPanel added to its ContentPane.JFrame Contains Menu when i click one of its Menu item i
need JInternal Frame to be added on top of the contentpane.The Code i have given so far,
JDesktopPane desktop = new JDesktopPane();
desktop.setLayout(new BorderLayout());
JPanel topPanel = new JPanel();
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[] { 0, 0, 0, 0 };
gbl_contentPane.rowHeights = new int[] { 0, 0, 0, 0 };
gbl_contentPane.columnWeights = new double[] { 1.0, 6.0, 1.0,
Double.MIN_VALUE };
gbl_contentPane.rowWeights = new double[] { 0.0, 8.0, 0.0,
Double.MIN_VALUE };
topPanel.setLayout(gbl_contentPane);
JPanel left = new JPanel();
GridBagConstraints gbc_left = new GridBagConstraints();
gbc_left.insets = new Insets(0, 0, 5, 5);
gbc_left.fill = GridBagConstraints.BOTH;
gbc_left.gridx = 0;
gbc_left.gridy = 1;
topPanel.add(left, gbc_left);
JPanel middle = new JPanel();
GridBagLayout gbl_middle = new GridBagLayout();
gbl_middle.columnWeights = new double[] { 1.0 };
middle.setLayout(gbl_middle);
GridBagConstraints gbc_middle = new GridBagConstraints();
gbc_middle.insets = new Insets(0, 0, 5, 5);
gbc_middle.fill = GridBagConstraints.BOTH;
gbc_middle.gridx = 1;
gbc_middle.gridy = 1;
topPanel.add(middle, gbc_middle);
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = gbc.weighty = 30;
middle.add(panel1, gbc);
panel1.setLayout(new MigLayout("", "[944.00,grow][353.00]",
"[6.00][128.00,grow][]"));
/*lblHeader = new JLabel(
"<html>Indira Institute of Technology<br>Tatabad<br>Karpagam Complex Stop<br>Coimbatre</html>");
lblHeader.setIcon(new ImageIcon(
"C:\\Users\\Prakash\\Desktop\\images.jpg"));
panel1.add(lblHeader, "cell 0 1 2 1,alignx center,aligny center");*/
JPanel panel2 = new JPanel();
gbc = new GridBagConstraints();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
gbc.insets = new Insets(2, 2, 2, 2);
middle.add(panel2, gbc);
panel2.setLayout(new MigLayout(
"",
"[30px][69.00px][144.00][68.00][][159.00px][59.00px][65px][28.00][]",
"[20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][20px:n,grow 50,shrink 50][30.00][48.00:n,grow 50,shrink 50]"));
getContentPane.add(topPanel);
I have never used the DesktopPane in this(I don't know how to make use of this in this situation) And The Screen So far is as follows,
Now I need the JInternalFrame to be added for the Previous Screen as Follows,
I am aware that i can only be able to add a JInternalFrame to the DesktopPane.But i
Already Filled my ContentPane with JPanel to show its content.How can i achieve Jinternal
Frame to be added in this JFrame.Kindly give your valuable suggestions.
Not really the right direction. You original panel is under the control of layout manager, this means that when you add the JInternalFrame to it, the layout manager wants to try and layout it out.
Generally speaking, a JInternalFrame wants to reside in a container which is unmanaged, allowing it to be positioned and sized independently of the content.
A possible solution might be to take advantage of the glass pane for the JInternalFrame instead, for more details see How to Use Root Panes
Another solution might be to use a JLayeredPane. Basically, you would start by setting the layout manager of the JLayeredPane to something link BorderLayout add the first panel to it and then add a second, transparent pane, with no layout, above it. You would add the JInternalFrames to this second panel.
See How to Use Layered Panes for more details
The question that jumps out at me though is...why? Why wouldn't you just use some kind of dialog instead? See How to Make Dialogs for more details
What is it what you really want?
You wrote you already have your content pane added to your frame. JDesktopPane has to have its own space reserved. If you don't have or you don't want to reserve space for the internal frames in your main frame, then maybe you don't even want it to be part of the main frame. In this case you might want to use child JDialogs instead of JInternalFrames.
So either add your JDesktopPane to your main frame (having its space reserved) or use child JDialogs which can be modal or not and can overlap any part of the main frame. JInternalFrames are only visible in the area of the JDesktopPane while child JDialogs can "float" over your main frame.
Check out this Oracle documentation: How to Use Internal Frames
And How to Make Dialogs.
I want to shorten my text field so it doesn't stretch to to the end of my jframe so this is how it looks now:
How do control the width of the textfield so it does't streatch like that I tried setPreferedSize() and setSize() yet they didn't work??
#Override
public void run() {
JFrame frame = new JFrame("Test Calculator");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setSize(500, 500);
JPanel panel = new JPanel(new GridBagLayout());
frame.getContentPane().add(panel, BorderLayout.NORTH);
GridBagConstraints c = new GridBagConstraints();
JLabel testLabel = new JLabel("Enter Score For Test 1: ");
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.BOTH;
c.insets = new Insets(40, 15, 15, 0);
panel.add(testLabel , c);
JTextField txtField1 = new JTextField("TextField");
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = .5;
panel.add(txtField1 , c);
}
You're telling the layout that the text field must fill horizontally, so that's what it does. Replace
c.fill = GridBagConstraints.HORIZONTAL;
by
c.fill = GridBagConstraints.NONE;
First and foremost, get rid of this:
frame.setSize(500, 500);
Instead let your components and layout managers size themselves by calling pack() on your JFrame after filling it and before setting it visible.
Next, consider either adding an empty border around your main container, or else adding an empty JLabel to your GridBagLayout using container.
You can also give your JTextField appropriate insets to give a cushion around it.
c.insets = new Insets(40, 15, 15, 40);
panel.add(txtField1, c);
You can change how many columns a particular component takes up by changing GridBagConstraints gridwidth field.
//this would make the next component take up 2 columns
c.gridwidth = 2;
You could have a jpanel and set its dimensions and layout, then add the elements to that panel and add the panel to your jframe.
There are different layout types that can be used depending on what you need to be done. I usually like to use Box's. They have methods that allow you to create horizontal/vertical struts, create rigid areas(this is what I usually use)
Box box1 = Box.createHorizontalBox();
Box box2 = Box.createVerticalBox();
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(testLabel);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box1.add(txtField1);
box1.add(Box.createRigidArea(new Dimension(30,0)));
box2.add(Box.createRigidArea(new Dimension(0,30)));
box2.add(box1);
box2.add(Box.createRigidArea(new Dimension(0,30)));
JFrame.add(box2);
Check this link out for descriptions and how to use all the different kinds of layouts: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
I've been learning Java Swing using GridBagLayout.
I have a main JFrame and add main JPanel, then I add subsequent JPanels/components to that main JPanel.
But anything I add it always positions to the center of the main panel (including while resize), which is not desired result.
Just a small snippet on the core code:
getContentPane().setLayout(new GridBagLayout());
JPanel panel = new JPanel(new GridBagLayout());
getContentPane().add(panel);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
JTextField nameField = new JTextField(10);
panel.add(nameField, gbc)
Any feedback would be appreciated, thanks.
In the future, post a SSCCE when you have a problem. A small "snippet" of code generally doesn't help.
Read the section from the Swing tutorial on How to Use GridbagLayout. The part on "weightx/weighty" will explain why this happens.
Is there any method I could implement that will ensure each button within the pane maintains a minimum height? I have attempted using itembutton.setSize() method but it has no effect.
JPanel itemPanel = new JPanel();
itemPanel.setLayout(new GridLayout(0,1));
for(final Item i: list){
JButton itemButton = new JButton(i.getName());
itemPanel.add(itemButton);
}
JScrollPane itemPane = new JScrollPane(itemPanel);
itembutton.setMinimumSize(minimumSize) ?
Edit: Just found that, as this java tutorial seems to tell, there is no way to do that with GridLayout.
Each component takes all the available space within its cell, and each cell is exactly the same size
So I guess you'll have to try another layout. I can suggest (don't know if it's well suited but it works) GridBagLayout. Example with 2 buttons:
itemPanel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.weightx = 0.5;
itemPanel.add(new JButton("A"), c);
c.gridx = 1;
c.weightx = 0.5;
itemPanel.add(new JButton("B"), c);
Have a look to http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html