Swing Components in Different Classes - java

probably a simple question here working on learning to make a GUI using swing and making mild headway but hit another speed bump. I am trying to keep GUI components grouped in different classes to keep my classes small and allow a more flexible GUI, but I have one component built how do I call it to my main class. Posted below is code to make the frame and the component. I would imagine there is an issue with the way I am calling but am running out of ideas on how else to call it. Any thoughts would be appreciated.....Wasn't very clear with the question trying to add the component to the JFrame in frmMainMenu, issue is that the component doesn't appear in the Frame when run currently
Main Class with JFrame
public class frmMainMenu {
public static void main(String main[]){
//Create Frame
JFrame frmMainMenu = new JFrame();
//Define Layout Manager
GridBagLayout gridBag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
frmMainMenu.setLayout(gridBag);
//Add Components
//Create Left Container
c.fill = GridBagConstraints.VERTICAL;
c.weighty = 1;
c.gridx = 0;
c.gridy = 1;
c.ipadx = 30;
frmMainMenu.add(new comLeftToolBar(),c);
frmMainMenu.setExtendedState(JFrame.MAXIMIZED_BOTH);
frmMainMenu.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//Display Frame
frmMainMenu.setVisible(true);
}
}
Component Code
public class comLeftToolBar extends JPanel{
public comLeftToolBar() {
JPanel comLeftContainer = new JPanel();
GridBagLayout leftGridBag = new GridBagLayout();
comLeftContainer.setLayout(leftGridBag);
GridBagConstraints b = new GridBagConstraints();
JToolBar comLeftToolBar = new JToolBar(JToolBar.VERTICAL);
b.gridx = 0;
b.gridy = 0;
b.ipady = 50;
JButton comNavButton = new JButton();
JButton comProButton = new JButton();
comLeftToolBar.add(comNavButton);
comLeftToolBar.add(comProButton);
comLeftContainer.add(comLeftToolBar,b);
comLeftContainer.setBorder(BorderFactory.createLineBorder(Color.black));
}
}

issue is that the component doesn't appear in the Frame when run currently
Your class is a panel. But then you create another panel (comLeftContainer) and add components to this panel. But you don't add any components to the ComLeftToolBar panel so it remains empty.
For a simple solution, at the bottom of your class you can use:
add( comLeftContainer );
Of course this is not the best solution. This will give you a structure of:
JPanel
JPanel
JToolbar
button
button
There is no need to have such a complicated structure. A toolbar is a component that be added directly to the frame.
If you want to create a class that you can add to the frame then take a look at the Swing tutorial on How to Use Tool Bars for a better structure.

Related

GridBagLayout is not working when I add it to the JFrame

I'm having some issues with my GridBagLayout. I have created a JPanel (in this case it's called mainPanel), whose layout has been set to GridBagLayout. I have specified the constraints for each JButton, and added the constraints to each button. Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints. Furthermore, the buttons are always at the center of the JFrame, when I would like one button to appear at the top right, top left, and south.
import javax.swing.*;
import java.awt.*;
public class test {
public static void main (String[] args) {
myJFrame test = new myJFrame();
}
}
class myJFrame extends JFrame {
public myJFrame () {
setSize(500,500);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainPanel myPanel = new mainPanel();
add(myPanel);
setVisible(true);
}
}
class mainPanel extends JPanel {
public mainPanel(){
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = 1000;
c.gridy= 1;
add(new JButton("1"),c);
c.anchor = GridBagConstraints.NORTHEAST;
c.gridx = 100;
c.gridy= 1;
add(new JButton("2"),c);
c.anchor = GridBagConstraints.SOUTH;
c.gridx = 200;
c.gridy= 1;
add(new JButton("3"),c);
}
}
This is what i get when i run the code
Now, when I run my code, the buttons are always next to each other, irrespective of the gridx/gridy value that I indicate in the constraints.
Correct, you can't just specify random cells. A component must be located in each cell.
Furthermore, the buttons are always at the center of the JFrame,
Yes, this is the default behaviour if you don't specify a weightx/weighty constraint.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on constraints and working examples.
Why are you picking random x locations like 100, 200, 1000? Maybe a horizontal BoxLayout would be a better layout manager. You can add the components and then add space between them:
panel.add( button1 );
panel.add( Box.createHorizonalStrut(100);
panel.add( button2 );
panel.add( Box.createHorizonalStrut(200);
Or maybe use a FlowLayout and specify the "gap" between each component.

JLabels not showing up

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).

gridheight doesn't affect my buttons

I am new in java applications and I am trying to create a window with 3 buttons in a row at the bottom of the window with extended size. However gridheight doesn't have any affect on my buttons. gridwidth works fine.
Can you give me a feedback on what I am doing wrong? I guess I haven't understand something correctly.
Bellow is my code and the output window.
Thanx in advance!
private JButton button1;
private JButton button2;
private JButton button3;
public SessionTasksPage()
{
JPanel p1=new JPanel(new GridBagLayout());
JPanel p2=new JPanel();
button1 = new JButton("b1");
button2 = new JButton("b2");
button3 = new JButton("b3");
GridBagConstraints gbc =new GridBagConstraints();
//gbc.insets = new Insets(1,1,1,1);
gbc.gridheight = 5;
gbc.gridwidth = 5;
gbc.weightx=15;
gbc.weighty=15;
gbc.fill = GridBagConstraints.BOTH;
p1.add(button2,gbc);
p1.add(button3,gbc);
p1.add(button1,gbc);
add(p1,BorderLayout.SOUTH);
add(p2,BorderLayout.NORTH);
EventHandler1 event1 = new EventHandler1();
button1.addActionListener(event1);
//window terminate setting
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//window size
setSize(600,400);
//pack();
//make window visible
setVisible(true);
//window title
setTitle("HCI-Projet");
//voice command
//new AePlayerWave("bin/sounds/login.wav").start();
}
public class EventHandler1 implements ActionListener
{
public void actionPerformed(ActionEvent event1) {
System.exit(0);
}
}
The problem lies the layout of your main panel. BorderLayout, which you use on that panel, has one large central area (BorderLayout.CENTER), and many smaller areas (such as NORTH and SOUTH). The layout will force anything put anywhere other than CENTER to take up the smallest amount of room possible, and max out the remaining room with what is in the CENTER area (with nothing, in this case). Since you're adding p1 as SOUTH, it keeps the vertical component of p1 as small as it can. If you add p1 as CENTER, it should fix your problem.
As a side note, if all the rows/columns in your grid will have the same height/width, you may find using GridLayout much easier than GridBagLayout.
The problem is the JPanel p1. The space of the panel is created by the standard layout, and if you just use add(p1,BorderLayout.SOUTH);, it won't change.
To make it visible you could use a Border:
p1.setBorder(BorderFactory.createLineBorder(Color.black));
Use a different layout or a GUI builder.

Several similar panels GUI Java

I'm creating GUI and I don't know how to resolve my problem. What I'd like to do is to create several panels from PanelClass like i did in Main.
I don't know how:
Name buttons in my Panels and gave them some functionality (Like i was trying with button b1)
Add to panel3 additional labels, and buttons.
My main class
public class Main {
JFrame f;
PanelClass panel1, panel2, panel3;
JButton b1, b2;
public Main() {
b1 = new JButton("asasa");
f = new JFrame();
f.setSize(300, 300);
f.setLayout(new GridBagLayout());
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel1 = new PanelClass(b1, b2, panel1);
panel2 = new PanelClass(b1, b2, panel2);
panel3 = new PanelClass(b1, b2, panel3);
f.add(panel1);
f.add(panel2);
f.add(panel3);
}
public static void main(String[] args) {
Main m = new Main();
}
}
My Panel class
public class PanelClass extends JPanel {
public PanelClass(JButton btn, JButton btn1, JPanel p) {
super();
p = new JPanel(new GridBagLayout());
btn = new JButton();
btn1 = new JButton();
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
p.add(btn, c);
c.gridx = 0;
c.gridy = 1;
p.add(btn1, c);
add(p);
}
}
A component can only exist in one visible container at a time (unless it is being used as a flyweight renderer). So putting the same buttons into 3 panels will not work.
The code passes a button(s) in the constructor of PanelClass which is(are) ignored. Instead 2 new button instances are created. Just assign the passed buttons to the ..I was going to say 'class level attributes' when I noted they were not. Entirely remove
btn = new JButton(); and the text passed in the button constructor will appear.
For events, see How to Write an Action Listener.
Try to read the official Swing tutorial. It explains how to add panels, labels, etc.
To edit label names you could use setText(String name) method. To add functionalities to buttons you must implement a listener in each one. Add labels like you do in other panels, I don't see the problem.
To add "events" like click and mouse hovers etc - you must implement the correct "Listener" for the Widget. Go through any good tutorial on Swing and it will tell you everything about it. Widgets on screen are regular objects as well, so they can be added to "Collections", iterated and played around with, like regular objects. Take note of THREAD complexities and warning 'Cross-Thread invocation is Injurious To Your Program'.

Issue with JPanel as scrollable

I am developing a java JApplet to display few 10s of check boxes in scrollable pane. I included these check boxes in JPanel and added this panel on JScrollPane which is added in current ContentPane of applet. Content pane also has few other components like JTextArea, Button and Label. I would see the scroll bar but when I do scrolling, check boxes are scrolled outside of scrollpane and laid over other adjacent components. I tried setPreferredSize() with no success. What could be the issue with scrolling?
My code bites looks like:
public void init(){
contentPane = this.getContentPane();
GridBagLayout grrdbag = new GridBagLayout();
GridBagConstraints components = new GridBagConstraints();
contentPane.setLayout(gridbag);
//button, textarea and label components here
//checkboxes here
components = new GridBagConstraints();
components.anchor = GridBagConstraints.EAST;
contentPane.add(new Label("Data:", Label.RIGHT), components);
components = new GridBagConstraints();
components.gridwidth = GridBagConstraints.REMAINDER;
components.weighty = 1;
components.fill = GridBagConstraints.BOTH;
checkboxesPanel.setLayout(new BoxLayout(checkboxesPanel, BoxLayout.Y_AXIS));
conflictScrollPane = new JScrollPane(checkboxesPanel,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
contentPane.add(conflictScrollPane, components);
}
//create check boxes
public void displayboxes(){
checkboxes = new Checkbox[150];
for(int j=0;j<150;j++){
checkboxes[j] = new Checkbox("This is test data for check box here.",null,false);
checkboxesPanel.add(checkboxes[j]);
checkboxesPanel.revalidate();
}
repaint();
validate();
}
//start method
public void start() {
displayboxes();
repaint();
validate();
}
If your example is to believed, you are mixing heavy weight and light weight components. My basic recommendation is, don't. They don't play nice together.
Change your references to Checkbox to JCheckBox instead.
Check out for more info
http://java.sun.com/products/jfc/tsc/articles/mixing/
http://java-antony.blogspot.com.au/2007/07/swing-vs-awt-or-lightweight-vs.html
Shane

Categories