I am trying to figure why I can't see my labels like when I try to put 2 labels into 1 panel they dissapear, the only way I can seem to get it to work is if I add everything to JFrame with no type of hierarchy.
import javax.swing.*;
import java.awt.*;
public class GUI extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
static JRadioButton tirebg1 = new JRadioButton();
static JRadioButton tirebg2 = new JRadioButton();
static JRadioButton tirebg3 = new JRadioButton();
static ButtonGroup tirebg = new ButtonGroup();
public static void main(String[] args) {
Car cspeed = new Car();
int carspeed = cspeed.getSpeed();
Motorcycle mspeed = new Motorcycle();
int motospeed = mspeed.getSpeed();
Truck tspeed = new Truck();
int truckSpeed = tspeed.getSpeed();
JRadioButton wide = new JRadioButton();
JLabel tbuttons = new JLabel();
JPanel topPane = new JPanel();
tirebg.add(tirebg1);
tirebg.add(tirebg2);
tirebg.add(tirebg3);
JFrame GUIframe = new JFrame();
JLabel label1 = new JLabel();
label1.setLayout(new FlowLayout());
JLabel tireLabel = new JLabel();
String[] names = new String[5];
names[0] = "Car";
names[1] = "Truck";
names[2] = "Motorcycle";
String[] hello = new String[5];
GUIframe.setSize(500, 500);
GUIframe.setDefaultCloseOperation(EXIT_ON_CLOSE);
JList list = new JList(names);
list.setBorder(BorderFactory.createRaisedSoftBevelBorder());
label1.add(list);
tireLabel.add(tirebg1);
tireLabel.add(tirebg2);
tireLabel.add(tirebg3);
topPane.add(tbuttons);
topPane.add(tireLabel);
topPane.setLayout(new FlowLayout());
label1.setBackground(Color.cyan);
GUIframe.add(topPane);
GUIframe.validate();
GUIframe.setBackground(Color.GREEN);
GUIframe.setVisible(true);
}
}
Since you posted a lot of code and I'm not sure what were you trying to achieve, I modified your code adding 3 JLabels at the topPane. And 3 JRadioButtons (I didn't add the ButtonGroup) below on a second JPanel, I commented how to make them appear on a vertical and horizontal align.
Something you should take into account is:
Don't extend and create objects from JFrame (One or the other, not both, I recommend you to create objects).
You were giving your JPanel a Layout after adding components to it, it should be done before.
From the above point, you were also giving your Layout to your JLabel not your JPanel.
You were adding a JList into a JLabel.
You missed to have a class constructor too.
Don't have multiple JFrames for more see The use of multiple JFrames, Good / Bad practice
Next time post a code which has no dependencies such as your Truck, Car and Motorcycle classes (i.e. a Runnable example). And use plain text instead so we can copy-paste the code and see the issue. Also try posting images (or the link and we can edit to add it).
Now, the outpus of my own program are:
And it was done with the following code.
import javax.swing.*;
import java.awt.*;
public class GUIExample {
JFrame frame;
JLabel label1, label2, label3;
JPanel topPane, radioPane;
JRadioButton radio1, radio2, radio3;
public static void main(String[] args) {
new GUIExample();
}
GUIExample () {
frame = new JFrame();
topPane = new JPanel();
radioPane = new JPanel();
topPane.setLayout(new FlowLayout());
// radioPane.setLayout(new BoxLayout(radioPane, BoxLayout.PAGE_AXIS)); //Vertical align
radioPane.setLayout(new FlowLayout()); //Horizontal align
label1 = new JLabel("Car");
label2 = new JLabel("Motorcycle");
label3 = new JLabel("Truck");
radio1 = new JRadioButton("Radio1");
radio2 = new JRadioButton("Radio2");
radio3 = new JRadioButton("Radio3");
topPane.add(label1);
topPane.add(label2);
topPane.add(label3);
radioPane.add(radio1);
radioPane.add(radio2);
radioPane.add(radio3);
frame.add(topPane, BorderLayout.PAGE_START);
frame.add(radioPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
Your code has several issues, but the reason that you're not seeing the tireLabel or the tbuttons component is because you're using a JLabel. Understand that JLabel is not built to act as a container for other components. The key concept is that it calculates its preferred size based on the text it holds and/or the icon it holds and (and this is key) not on the sizes or preferred sizes of any components it might hold.
The solution is to not use JLabel for a purpose it wasn't intended for but rather to use a JPanel which does adjust its own preferred size depending on the sizes of its held components and its layouts.
Other unrelated issues:
Your program extends JFrame but never uses itself as a JFrame, something that will confuse anyone who reads your code. If you're not going to use the instance of the class as a JFrame, then don't extend the class.
Your program isn't an OOP-compliant program, one with instance fields, public methods, and such, but rather is little more than one large static main method, and this will result in a large God-method, one with too much responsibility, and one that is very difficult to debug and to maintain. Don't throw out the OOP baby with the bath water -- Create Swing GUI's in a well-behaved OOP-compliant way.
You're trying to set background colors to components that are not opaque (a JLabel), to components that are never added to the GUI (label1), or are not fully displayed (the JFrame).
You're using FlowLayout an awful lot, and in places where other layouts would probably serve you better. It's as if it's the only layout that you know how to use, and so you use it. Try branching out and using other layouts including GridLayout for your JRadioButton container and perhaps BorderLayout for the main container (JPanel).
Related
I'm using the NetBeans GUI builder to handle my layout (I'm terrible with LayoutManagers) and am trying to place a simple JLabel so that it is always centered (horizontally) inside its parent JPanel. Ideally, this would maintain true even if the JPanel was resized, but if that's a crazy amount of coding than it is sufficient to just be centered when the JPanel is first created.
I'm bad enough trying to handle layouts myself, but since the NetBeans GUI Builder autogenerates immutable code, it's been impossible for me to figure out how to do this centering, and I haven't been able to find anything online to help me.
Thanks to anybody who can steer me in the right direction!
Here are four ways to center a component:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
class CenterComponent {
public static JLabel getLabel(String text) {
return getLabel(text, SwingConstants.LEFT);
}
public static JLabel getLabel(String text, int alignment) {
JLabel l = new JLabel(text, alignment);
l.setBorder(new LineBorder(Color.RED, 2));
return l;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JPanel p = new JPanel(new GridLayout(2,2,4,4));
p.setBackground(Color.black);
p.setBorder(new EmptyBorder(4,4,4,4));
JPanel border = new JPanel(new BorderLayout());
border.add(getLabel(
"Border", SwingConstants.CENTER), BorderLayout.CENTER);
p.add(border);
JPanel gridbag = new JPanel(new GridBagLayout());
gridbag.add(getLabel("GridBag"));
p.add(gridbag);
JPanel grid = new JPanel(new GridLayout());
grid.add(getLabel("Grid", SwingConstants.CENTER));
p.add(grid);
// from #0verbose
JPanel box = new JPanel();
box.setLayout(new BoxLayout(box, BoxLayout.X_AXIS ));
box.add(Box.createHorizontalGlue());
box.add(getLabel("Box"));
box.add(Box.createHorizontalGlue());
p.add(box);
JFrame f = new JFrame("Streeeetch me..");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(p);
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
});
}
}
By using Borderlayout, you can put any of JComponents to the CENTER area. For an example, see an answer to Stack Overflow question Get rid of the gap between JPanels. This should work.
Even with BoxLayout you can achieve that:
JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.X_AXIS ));
JLabel label = new JLabel();
listPane.add(Box.createHorizontalGlue());
listPane.add(label);
listPane.add(Box.createHorizontalGlue());
mKorbel's solution is perfect for your goal. Anyway I always like to suggest BoxLayout because it's very flexible.
Mara: "thanks for your response, however the NetBeans GUI Build uses GroupLayout and this is not overridable."
Not true! Right click anywhere inside JFrame (or any other GUI container) in NetBeans GUI builder and select "Set Layout". By default is selected "Free Design", which is Group layout, but you can select any other layout including Border layout as advised by mKorbel.
There's many ways to do this, depending on the layout manager(s) you use. I suggest you read the Laying Out Components Within a Container tutorial.
I believe the following will work, regardless of layout manager:
JLabel.setHorizontalAlignment(SwingConstants.CENTER)
I am new to Java and especially new to GUI and it's super confusing to me right now.
I'm making a program for class that is supposed to have a menu (JComboBox I'm assuming) that opens a new window when an option is selected. I am just working on the first option where you click "The Matrix" and a new window pops up with two buttons called "Red Pill" & "Blue Pill" and thats where I've hit a wall.
I got to the point where I am able to create a new window (not sure if this is even the right route to take for opening the new window) but, When I try to add Buttons to the new pop up window nothing shows up....
Thanks for any help or pointers in the right direction!
public class MultiForm extends JFrame{
private JComboBox menu;
private JButton bluePill;
private JButton redPill;
private static String[] fileName = {"", "The Matrix", "Another Option"};
public MultiForm() {
super("Multi Form Program");
setLayout(new FlowLayout());
menu = new JComboBox(fileName);
add(menu);
TheHandler handler = new TheHandler();
menu.addActionListener(handler);
}
private class TheHandler implements ActionListener{
public void actionPerformed(ActionEvent event) {
********************************************************************
//Create a new window when "The Matrix" is clicked in the JCB
JFrame newFrame = new JFrame();
JPanel panel = new JPanel();
newFrame.setLayout(new FlowLayout());
newFrame.setSize(500, 300);
newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);
Icon bp = new ImageIcon(getClass().getResource("Blue Pill.png"));
bluePill = new JButton("Blue Pill", bp);
newFrame.add(bluePill);
Icon rp = new ImageIcon(getClass().getResource("Red Pill.png"));
redPill = new JButton("Red Pill", rp);
newFrame.add(redPill);
add(panel);
newFrame.setVisible(true);
}
}
public static void main(String[] args) {
MultiForm go = new MultiForm();
go.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
go.setSize(400, 200);
go.setVisible(true);
}
}
I tried doing newFrame.add(BluePill) and it created a button that was the size of the entire window and it would not allow me to add both buttons that way
That's because the frame uses a BorderLayout by default. Unless you specify otherwise, the component's will be added to the CENTER position, BUT, BorderLayout will only allow a single component to be managed at each of the it's five available positions, so you are only seeing the last component you added.
See How to Use BorderLayout for more details
so I figured that wasn't the correct way
It's the right approach, you just need to use a layout manager which can accommodate more components or change the position which you are adding the buttons
In this little example, I've just use a FlowLayout, but you can use what ever is going to give you the effect you desire
JFrame newFrame = new JFrame();
newFrame.setLayout(new FlowLayout());
newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);
bluePill = new JButton("Blue Pill");
newFrame.add(bluePill);
redPill = new JButton("Red Pill");
newFrame.add(redPill);
newFrame.pack();
newFrame.setVisible(true);
As a general rule of thumb, I don't like adding components like this directly to a top level container, I prefer to use a intermediate container, like a JPanel, this gives me more possibilities for re-use, but that's me.
You should also only make the frame visible when it's actually ready, otherwise you may find that some times, the components won't show up
See Laying Out Components Within a Container for more details
You are not using the getContentPane() method from the new JFrame.
You have to actually use getContentPane() first because you're not adding any component to the JFrame itself but to an intermediate "panel".
JFrame newFrame = new JFrame();
JPanel panel = new JPanel();
newFrame.setSize(300, 200);
newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);
bluePill = new JButton("Blue Pill");
panel.add(bluePill);
redPill = new JButton("Red Pill");
panel.add(redPill);
newFrame.getContentPane().add(panel);
newFrame.setVisible(true);
You'll have to add a Layout to the JPanel or/and the JFrame and play with the sizes of the component but with this you're on the right path.
I always put the setVisible method a the end, after adding all the components to the frame.
You made some mistakes.
add(bluePill);
will not do what you want, even if it would, it would still be wrong.
(sounds weird, but I'll explain it)
First the "right" way to do it:
//Create a new window when "The Matrix" is clicked in the JCB
JFrame newFrame = new JFrame();
newFrame.setSize(300, 200);
newFrame.setDefaultCloseOperation(newFrame.EXIT_ON_CLOSE);
bluePill = new JButton("Blue Pill");
newFrame.getContentPane().add(bluePill);
redPill = new JButton("Red Pill");
newFrame.getContentPane().add(redPill);
newFrame.setVisible(true);
Notice I added "newFrame", because you were calling the method of MultiForm.
That's because "add()" is the same as "this.add()" and "this" points to MultiForm. Check it with this line if you want:
System.out.println(this.toString());
The "getContentPane()" is best explained with this image:
You were adding it directly to the JFrame (I don't even know what exactly happens then).
It is also good practice to set the frame visible when it is ready to be visible. Your frame did not contain anything when you made it visible.
Now to the JPanel. A JPanel can hold some elements like JButton,etc. and it can also have a layout. Since you didn't use the JPanel at all, i removed the line from your code. You can still add the JPanel to your ContentPane and add a Layout to the JPanel. (You can also add JPanels to JPanels to create complex layouts)
I hope this was clear for you.
First time posting here, and let me first say that I'm a bit of a Java noob, I've only started learning it in uni this year.
So anyway, I have to create a UI for a Tamagotchi project, and I'm trying to create it using JFrame etc.
This is what I'm trying to create:
This is my code so far:
import javax.swing.*;
import java.awt.*;
public class DogUI {
private JFrame DogUI;
private JPanel leftPanel, topPanel, bottomPanel, rightPanels;
private JButton jb;
private JLabel lb, lb1, lb2;
public DogUI() {
GUI();
}
public void GUI() {
DogUI = new JFrame("Dog UI");
DogUI.setSize(800, 600);
DogUI.setResizable(false);
leftPanel = new JPanel();
leftPanel.setBackground(Color.green);
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
topPanel = new JPanel();
topPanel.setBackground(Color.white);
bottomPanel = new JPanel();
bottomPanel.setBackground(Color.red);
rightPanels = new JPanel();
rightPanels.setLayout(new BoxLayout(rightPanels, BoxLayout.X_AXIS));
DogUI.setVisible(true);
lb = new JLabel("Name: ");
leftPanel.add(lb);
lb1 = new JLabel("Image");
topPanel.add(lb1);
lb2 = new JLabel("Buttons");
bottomPanel.add(lb2);
rightPanels.add(topPanel);
rightPanels.add(bottomPanel);
DogUI.add(rightPanels);
}
public static void main(String [] args) {
new DogUI();
}
}
This is what I end up with:
I'm sure it's something simple, or perhaps I am going the complete wrong way about doing it, but please try explain it in layman's terms if possible.
Thanks.
Chris.
You are only adding the rightPanels to the frame, you never add leftPanel
The rightPanel is using X_AXIS which is horizontal. You want Y_AXIS
When you do add the leftPanel, you're going to want to set your frame's layout to GridLayout(1, 2). See GridLayout
setVisible after adding all your components.
Follow Java namingConvention. variables begin with lower case, using camel casing. DogUI → dogUI
Swing apps should be run from the Event Dispatch Thread (EDT). You can do this by wrapping the code in the main in a SwingUtilities.invokeLater(...). See more at Initial Threads
Try using a GridLayout instead.
public void GUI() {
DogUI = new JFrame("Dog UI");
DogUI.setSize(800, 600);
DogUI.setResizable(false);
DogUI.setLayout(new GridLayout(1,2));//1row 2col
leftPanel = new JPanel();
leftPanel.setBackground(Color.green);
topPanel = new JPanel();
topPanel.setBackground(Color.white);
bottomPanel = new JPanel();
bottomPanel.setBackground(Color.red);
rightPanels = new JPanel();
rightPanels.setLayout(new GridLayout(2,1));//2row 1col
lb = new JLabel("Name: ");
leftPanel.add(lb);
lb1 = new JLabel("Image");
topPanel.add(lb1);
lb2 = new JLabel("Buttons");
bottomPanel.add(lb2);
rightPanels.add(topPanel);
rightPanels.add(bottomPanel);
DogUI.add(leftPanel);
DogUI.add(rightPanels);
DogUI.setVisible(true);
}
It sounds like you want a parent JPanel with a BorderLayout. That parent JPanel contains two other panels, on the east and west side of it. The west side can contain your progress panel, and the east side contains another JPanel, which has a GridLayout of 1 column and 2 rows, or alternatively, a BorderLayout. From there you can add the other two JPanels to that last JPanel which represent whatever that right hand side of the picture shows.
The overall parent JPanel could also be a GridLayout with 2 columns and 1 row, but a BorderLayout might look better as you might find one side of the application might not need as much space and might limit how much space it takes up. Perhaps the east panel should be a BorderLayout too as your image might not take up that much space on the north side giving the components on the south side the rest of the container's available space.
I'm playing around with some swing guis and am trying to create a basic program. This program is going to have a tabbed pane with a varying amount of tabs depending on the size of an array. (My end goal is to have users change the amount of items in the array, therefore changing the amount of tabs).
Each tab is going to have the exact same components, text area, table and a few buttons and labels. What I would like to do is instead of coding these tabs individually and rewriting my code over and over what I want to do is create a class to put all my components into.
I am however kind of stumped. This is my class for creating the tabs:
public class LocaleTab {
public LocaleTab(){
JPanel tab = new JPanel();
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
tab.add(label);
}
}
And here's my code that I'm trying to call with it:
LocaleTab tab1 = new LocaleTab();
JTabbedPane localesTabPane = new JTabbedPane();
localesTabPane.add(tab1);
I'm getting an error when I try and compile this. I'm thinking my methodology is probably completely wrong.
The method add(Component) in the type JTabbedPane is not applicable
for the arguments (LocaleTab)
One are that concerns me is when I try to use the data in the tables and text areas in each tab(event listeners is what I'll be using i think? I haven't gotten to that stage yet though!) how will I target the individual tabs components?
Change to:
public class LocaleTab extends JPanel {
public LocaleTab(){
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
add(label);
}
}
Probably you are looking for something close to this:
public class LocaleTab {
private JPanel tab;
public LocaleTab() {
tab = new JPanel();
JLabel label = new JLabel();
label.setPreferredSize(new Dimension(300, 300));
tab.add(label);
}
public JPanel getTabPanel() {
return tab;
}
}
And use LocaleTab as shown below.
LocaleTab tab1 = new LocaleTab();
JTabbedPane localesTabPane = new JTabbedPane();
localesTabPane.add(tab1.getTabPanel());
Additionally to know about how JTabbedPane works please take a look here: How to Use Tabbed Panes
here's my problems : I tried to create a simple interface from where I can click on several buttons that call differents functions, and show the result (which always is text) in a jlabel.I tried to have 2 separates parts (north/south or east/west) The first area would contain a gridlayout or flowlayout of all my buttons and the 2nd area would show the text result.
Here are my declarations :
private static JButton b0 = new JButton("Creer Zone");
private static JButton b1 = new JButton("1");
private static JButton b2 = new JButton("2");
...
private static JButton b11= new JButton("11");
private static JButton b12 = new JButton("12");
private static JButton b14 = new JButton("Help");
private static JFrame windows = new JFrame();
private static JPanel container = new JPanel();
private static JLabel res = new JLabel();
and here is how i added them to the JFrame (which is really awfull to see) :
container.add(b0);
container.add(b1);
container.add(b2);
...
container.add(b12);
container.add(b14);
container.add(res);
windows.setSize(450,500);
windows.setContentPane(container);
windows.setLocation(150 , 150);
windows.setVisible(true);
I've tried to declare my jpanel with a gridlayout, a borderlayout and change the location (N S E W) and a flowlayout, i always ended up with the jlabel disapearing (which is bad because this jlabel show the result of my functions)
Any one have a simple way to help me overcome this ? Thanks a lot for any time you take
nicely explained on http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
Another possible solution for your future endeavors is to look into WindowsBuilder. It basically simplifies your layout design by allowing you to just simply drag and drop your elements (Jframe, JtextField, etc) and then in the background WindowsBuilder will write the code for you. Mind you the only thing that you will have to really add/change is the naming conventions of the buttons and of course the eventHandlers, but honestly those are something that any designer would want to control... Hopefully this helps you!
https://developers.google.com/java-dev-tools/wbpro/