I'm in the middle of working on a program. I created a JFrame with a bunch of panels, buttons, labels and textfields that are supposed to be inside it. For some reason the JFrame apears, but with nothing inside it. Here's the code:
import javax.swing.*;
import java.awt.*;
import java.awt.Event.*;
public class GUI extends JFrame {
JButton rect,oval,tri,free,addPoint;
JLabel xLabel,yLabel;
JTextField xTextField,yTextField;
JPanel leftPanel,rightPanel,optionsPanel,pointsPanel;
public GUI(){
initUI();
}
private void initUI(){
setLayout(new GridLayout(1,2,5,5));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Graphics Generator");
setSize(500,500);
setVisible(true);
add(leftPanel);
add(rightPanel);
leftPanel.setLayout(new GridLayout(2,1,5,5));
leftPanel.add(optionsPanel);
optionsPanel.setLayout(new GridLayout(1,4,2,2));
rect = new JButton("Rectangle");
oval = new JButton("Oval");
tri = new JButton("Triangle");
free = new JButton("Free Shape");
optionsPanel.add(rect);
optionsPanel.add(oval);
optionsPanel.add(tri);
optionsPanel.add(free);
leftPanel.add(pointsPanel);
pointsPanel.setLayout(new GridLayout(1,5,2,2));
pointsPanel.add(xLabel);
pointsPanel.add(xTextField);
pointsPanel.add(yLabel);
pointsPanel.add(yTextField);
pointsPanel.add(addPoint);
}
public static void main(String[] args) {
GUI gui = new GUI();
}
}
your JComponents aren't initialized,
you added JComponents to already visible JFrame,
you have to move code line setVisible(true); to the end of constructor,
Swing GUI should be crated on Initial Thread
You should invoke setVisible(true) after you're done adding your components. They won't render otherwise until there's a call to revalidate();
You also need to initialise your components before trying to use them.
Example:
leftPanel = new JPanel();
rightPanel = new JPanel();
add(leftPanel);
add(rightPanel);
Repeat for the other components.
None of your panels, textfields, or labels have been initialized. I'm getting NullPointerException
The code below will get your program running. But you really need to look into some LayoutManagers
private void initUI(){
leftPanel = new JPanel();
rightPanel = new JPanel();
optionsPanel = new JPanel();
pointsPanel = new JPanel();
yLabel = new JLabel();
xLabel = new JLabel();
xTextField = new JTextField();
yTextField = new JTextField();
add(leftPanel);
add(rightPanel);
leftPanel.setLayout(new GridLayout(2,1,5,5));
leftPanel.add(optionsPanel);
optionsPanel.setLayout(new GridLayout(1,4,2,2));
rect = new JButton("Rectangle");
oval = new JButton("Oval");
tri = new JButton("Triangle");
free = new JButton("Free Shape");
addPoint = new JButton("Add Point");
optionsPanel.add(rect);
optionsPanel.add(oval);
optionsPanel.add(tri);
optionsPanel.add(free);
leftPanel.add(pointsPanel);
pointsPanel.setLayout(new GridLayout(1,5,2,2));
pointsPanel.add(xLabel);
pointsPanel.add(xTextField);
pointsPanel.add(yLabel);
pointsPanel.add(yTextField);
pointsPanel.add(addPoint);
setLayout(new GridLayout(1,2,5,5));
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Graphics Generator");
setSize(500,500);
setVisible(true);
}
Related
I am having a problem with BorderLayout, that was set to the green JPanel side. It does not display elements on the EAST in a row order. Do I have to combine this with GridBagLayout ? Could someone advice me how should I tackle this problem?
Basically the problem is of displaying objects inside green area below when I am using
Current layout:
My aim is to achieve this layout:
public class GUILayout {
public static void main(String[] args) {
JFrame jf = new JFrame();
JButton jbO = new JButton("CSIS0396");
JButton jbl = new JButton("Final");
JButton jb2 = new JButton("2010");
JButton jb3 = new JButton("Exam");
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
JButton object_btn = new JButton("Object");
JButton oriented_btn = new JButton("Oriented");
JButton programming_btn = new JButton("Programming");
JButton and_btn = new JButton("and");
JButton java_btn = new JButton("Java");
BorderLayout layout = new BorderLayout();
panel.setLayout(layout);
panel2.setLayout(layout);
panel.add(BorderLayout.CENTER,object_btn);
panel.add(BorderLayout.WEST,oriented_btn);
panel.add(BorderLayout.WEST,programming_btn);
panel.add(BorderLayout.WEST,and_btn);
panel.add(BorderLayout.WEST,java_btn);
panel2.add(BorderLayout.NORTH, jbO);
panel2.add(BorderLayout.SOUTH, jb2);
panel2.add(BorderLayout.WEST, jbl);
panel2.add(BorderLayout.EAST, jb3);
panel.setBackground(Color.GREEN);
panel2.setBackground(Color.RED);
jf.getContentPane().add(panel);
jf.getContentPane().add(panel2, BorderLayout.EAST);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 300);
jf.setVisible(true);
}
}
don't share same layout for multiple component and use box layout for left panel to positioning buttons
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUILayout {
public static void main(String[] args) {
JFrame jf = new JFrame();
JButton jbO = new JButton("CSIS0396");
JButton jbl = new JButton("Final");
JButton jb2 = new JButton("2010");
JButton jb3 = new JButton("Exam");
JPanel panel = new JPanel();
JPanel panel2 = new JPanel();
JButton object_btn = new JButton("Object");
JButton oriented_btn = new JButton("Oriented");
JButton programming_btn = new JButton("Programming");
JButton and_btn = new JButton("and");
JButton java_btn = new JButton("Java");
BorderLayout layout = new BorderLayout();
panel2.setLayout(layout);
panel.setLayout( new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(object_btn);
panel.add(oriented_btn);
panel.add(programming_btn);
panel.add(and_btn);
panel.add(java_btn);
panel2.add(BorderLayout.NORTH, jbO);
panel2.add(BorderLayout.SOUTH, jb2);
panel2.add(BorderLayout.WEST, jbl);
panel2.add(BorderLayout.EAST, jb3);
panel.setBackground(Color.GREEN);
panel2.setBackground(Color.RED);
jf.setLayout(new BorderLayout());
jf.getContentPane().add(panel ,BorderLayout.WEST);
jf.getContentPane().add(panel2, BorderLayout.EAST);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(400, 300);
jf.setVisible(true);
}
}
The first problem is that you're having your panels share a layout. You must use a new BorderLayout for each of them.
The second problem is that a BorderLayout can only have one component in each constraint position. When you try to add multiple components to the WEST position, each one replaces the one that was previously in that position:
panel.add(BorderLayout.WEST,oriented_btn);
// Implicitly removes oriented_btn from panel
panel.add(BorderLayout.WEST,programming_btn);
// Implicitly removes programming_btn from panel
panel.add(BorderLayout.WEST,and_btn);
// Implicitly removes and_btn from panel
panel.add(BorderLayout.WEST,java_btn);
The solution is to put them in their own container, such as a Box or a JPanel with a GridLayout:
Box box = Box.createVerticalBox();
// Or:
//JComponent box = new JPanel(new GridLayout(0, 1));
box.add(oriented_btn);
box.add(programming_btn);
box.add(and_btn);
box.add(java_btn);
panel.add(BorderLayout.WEST, box);
I wrote a program to compose a GUI using swing/awt framework for my assignment. So far, I am able to get the pieces working together, but when I put them all into a JFrame, they are not coming out as expected.
I have recently started working on Java GUI framework, and not sure what is missing in my code. How can I get this working properly?
I am also attaching the screen shots (see at the bottom) of the output I am getting.
public class MainFrame extends JFrame {
public MainFrame() {
addComponentsToPane(this.getContentPane());
}
private void addComponentsToPane(Container pane) {
// Set layout
GridBagConstraints gbc = new GridBagConstraints();
this.setTitle("Test tool");
this.setSize(600, 650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new GridLayout(2, 1));
// Add video JComponent
mMainPanel = new MainPanel();
pane.add(mMainPanel, 0);
// Add conference screen panel
mFeedPanel = new FeedPanel();
pane.add(mFeedPanel, 1);
// Add a button panel
mButtonPanel = new ButtonPanel();
pane.add(mButtonPanel, 2);
this.setResizable(true);
this.setVisible(true);
this.pack();
}
}
// In actual output, there is 1 screen in this panel.
// mScreen1 is derived from JComponent object.
public class MainPanel() extends JPanel {
public MainPanel() {
addMainPanelComponents();
}
private void addMainPanelComponents() {
this.setSize(352, 240);
setBackground(Color.yellow);
setLayout(new GridLayout(1, 2));
add(mScreen);
setVisible(true);
}
}
// In actual output, there are 3 screens in this panel. I have shown code for 1 screen only
// mScreen1 is derived from JComponent object.
public class FeedPanel extends JPanel {
public FeedPanel() {
addFeedPanelComponents();
}
private void addFeedPanelComponents() {
String img1 = "images/screen1.png";
setSize(352, 150);
setBackground(Color.yellow);
setLayout(new GridLayout(1, 3));
Image image1 = ImageIO.read(new File(img1));
mScreen1.setImage(image1);
add(mScreen1);
setVisible(true);
}
}
public class ButtonPanel extends JPanel {
public ButtonPanel() {
addButtonPanelComponents();
}
private void addButtonPanelComponents() {
this.setSize(352, 150);
this.setBackground(Color.yellow);
this.setLayout(new GridLayout(1,
5));
// Add Button to panel
mStartButton = new JButton("Start");
this.add(mStartButton);
mStartButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
StartButtonActionListener(ae);
}
});
mStopButton = new JButton("Stop");
this.add(mStopButton);
mStopButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
StopButtonActionListener(ae);
}
});
setVisible(true);
}
}
This comes by default on running the code.
This comes after manually resizing the frame.
The combination of BorderLayout , GirdLayout and BoxLayout can do this for you(Actually it's not the only choice).
Here is the code:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class GridLayoutTest {
public void createUI(){
JFrame frame = new JFrame();
JPanel topPanel = new TopPanel();
JPanel buttomPanel = new ButtomPanel();
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
mainPanel.add(topPanel,BorderLayout.CENTER);
mainPanel.add(buttomPanel,BorderLayout.SOUTH);
frame.add(mainPanel,BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
GridLayoutTest test = new GridLayoutTest();
test.createUI();
}
#SuppressWarnings("serial")
class TopPanel extends JPanel{
public TopPanel(){
setLayout(new GridLayout(2, 3));
ImageIcon icon = new ImageIcon("capture.png");
JLabel label1 = new JLabel(icon);
label1.setVisible(false);
JLabel label2 = new JLabel(icon);
JLabel label3 = new JLabel(icon);
label3.setVisible(false);
JLabel label4 = new JLabel(icon);
JLabel label5 = new JLabel(icon);
JLabel label6 = new JLabel(icon);
add(label1);
add(label2);
add(label3);
add(label4);
add(label5);
add(label6);
}
}
#SuppressWarnings("serial")
class ButtomPanel extends JPanel{
public ButtomPanel(){
JButton startButton = new JButton("start");
JButton stopButton = new JButton("stop");
JButton recordButton = new JButton("record");
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(Box.createHorizontalGlue());
add(startButton);
add(Box.createHorizontalStrut(10));
add(stopButton);
add(Box.createHorizontalStrut(10));
add(recordButton);
add(Box.createHorizontalGlue());
}
}
}
BoxLayout is so good too provide white space and help you to center the component.
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
add(Box.createHorizontalGlue());
add(startButton);
add(Box.createHorizontalStrut(10));
add(stopButton);
add(Box.createHorizontalStrut(10));
add(recordButton);
add(Box.createHorizontalGlue());
Add Glue before the first component and after the last component will help you too center the component and add strut can help you to provide white space you want. you can refer to https://stackoverflow.com/a/22525005/3378204 for more details.
Here is the effect:
The BoxLayout won't affect your component's size. Hope it can help you.
Try this :
public class Main{
private JFrame f;
private JLabel l1, l2, l3,l4;
private JPanel p1, p2, p3;
private JButton b1, b2, b3;
public Main(){
this.f = new JFrame();
this.f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.f.setLayout(new GridLayout(3,1));
this.p1 = new JPanel();
this.p1.setLayout(null)
this.p1.setSize(yoursize);
this.l1 = new JLabel();
this.l1.setBounds(x,y,xspan,yspan);
this.p1.add(l1);
this.p2 = new JPanel();
this.p2.setLayout(new GridLayout(1,3));
this.l2 = new JLabel();
this.l3 = new JLabel();
this.l4 = new JLabel();
this.p2.add(l2);
this.p2.add(l3);
this.p2.add(l4);
this.p3 = new JPanel();
this.p3.setLayout(new GridLayout(1,3));
this.b1 = new JButton();
this.b2 = new JButton();
this.b3 = new JButton();
this.p3.add(b1);
this.p3.add(b2);
this.p3.add(b3);
this.f.add(p1);
this.f.add(p2);
this.f.add(p3);
this.f.pack();
this.f.setResizeable(false)
}}
Add your video components instead of labels and you can change the color of the components as you wish.
Also if you want more control over the size and position of the components, use null layout and place them individually using setBounds() function as once shown in the program above. It is surely time consuming but makes the layout perfect.
What is wrong with my code? My buttons and the labels are not appearing.
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class HelloPanelLabel extends JFrame {
public static void main(String[] args) {
new HelloPanelLabel(); // creates an instance of frame class
}
public HelloPanelLabel() {
this.setSize(200, 100);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Hello World!");
this.setVisible(true);
Toolkit tk=Toolkit.getDefaultToolkit();
Dimension d= tk.getScreenSize();
int x=(d.height/2);
int y=(d.width/2);
this.setLocation(x, y);
//JPanel panel1 = new JPanel();
JLabel label1 = new JLabel("hello, world");
//panel1.add(label1);
JButton button1 = new JButton("Click me!");
//panel1.add(button1);
this.setVisible(true);
}
}
The reason for not showing of JButton and JLabel is that you have not added the JPanel containing these two components to the JFrame.You just need a little modification in your code. Here is that:
panel1.add(label1);
JButton button1 = new JButton("Click me!");
panel1.add(button1);
getContentPane().add(panel1);//Add to ContentPane of JFrame
this.setVisible(true);
And remove the the previous this.setVisible(true) line in your programe.
You need to set a layout and add your components to the frame.
setLayout(new FlowLayout());
//JPanel panel1 = new JPanel();
JLabel label1 = new JLabel("hello, world");
add(label1);
//panel1.add(label1);
JButton button1 = new JButton("Click me!");
add(button1);
//panel1.add(button1);
this.setVisible(true);
Like the comments stated, you have to call pack(). However, if you want to define more complex layouts, you will have to create a more complex.
If you want to use a JPanel for your components
public class HelloPanelLabel extends JFrame {
public static void main(String[] args) {
new HelloPanelLabel().setVisible(true);
}
public HelloPanelLabel() {
//The same as setTitle.
super("Hello World!");
JPanel panel1 = new JPanel();
JLabel label1 = new JLabel("hello, world");
panel1.add(label1);
JButton button1 = new JButton("Click me!");
panel1.add(button1);
add(panel1);
//Size the frame to fit the components
pack();
//Center the frame.
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
alternatively you can add them directly to the contentPane of the JFrame.
setLayout(new FlowLayout());
JLabel label1 = new JLabel("hello, world");
add(label1);
JButton button1 = new JButton("Click me!");
add(button1);
Toolkit theKit = getToolkit();
Dimension wndSize = theKit.getScreenSize();
setSize(wndSize.width / 8, wndSize.height / 12);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
How can I make buttons like this?
JPanel jp = new JPanel();
JPanel jpB1 = new JPanel();
JPanel jpB2 = new JPanel();
JPanel jpB3 = new JPanel();
JButton jb1 = new JButton("button1");
JButton jb2 = new JButton("button2");
JButton jb3 = new JButton("button3");
...
JLabel jl = new JLabel("label");
...
jp.setLayout(new BorderLayout());
...
jpB1.add(jb1);
jpB2.add(jb2);
jpB3.add(jb3);
...
jp.add(jpB1, BorderLayout.NORTH);
jp.add(jpB2, BorderLayout.CENTER);
jp.add(jpB3, BorderLayout.SOUTH);
...
I tried this code on creating 3 panels and add them to the main panel. It shows two buttons on north and one button on south! Can someone help me?
Note, the default layout of JPanel is FlowLayout; a GridBagLayout with default constraints is centered in the frame's BorderLayout.CENTER. Also, pack() the enclosing Window and display it last. Using Initial Threads left as an exercise.
Addendum: A useful trick for solving layout problems is setting the background color of an enclosing container to a contrasting color, for example
jpB2.setBackground(Color.blue);
import java.awt.BorderLayout;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Bouton2 {
public static void main(String[] args) {
final int LARGEUR = 400;
final int HAUTEUR = 300;
JFrame jf = new JFrame();
JPanel jp = new JPanel();
JPanel jpB1 = new JPanel();
JPanel jpB2 = new JPanel(new GridBagLayout());
JPanel jpB3 = new JPanel();
JButton jb1 = new JButton("Cliquez ici");
JButton jb2 = new JButton("Je compte");
JButton jb3 = new JButton("J'agrandis");
JLabel jl = new JLabel("0 clic");
jp.setLayout(new BorderLayout());
jpB1.add(jb1);
jpB2.add(jb2);
jpB3.add(jb3);
jp.add(jpB1, BorderLayout.NORTH);
jp.add(jpB2, BorderLayout.CENTER);
jp.add(jpB3, BorderLayout.SOUTH);
jf.setTitle("FenĂȘtre Bouton2");
jf.setContentPane(jp);
jf.pack();
jf.setSize(LARGEUR, HAUTEUR);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
}
I just started to learn swing by myself, I'm little bit confused why my event does not work here:
1.I'm trying to delete everything from my panel if the user click menu bar -> load but it force me to change the panel to final because i'm using it inside the event!
2.I have defined new panel in my event and defined two more container to add to that panel and then add it to the main frame but it seems nothing happening!
Please help me if you can find out what is wrong.
Sorry in advance for messy code.
I appreciate any hints.
public class SimpleBorder {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run()
{
myFrame frame = new myFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class MyFrame extends JFrame {
public MyFrame()
{
setSize(500,500);
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel label = new JLabel("my name is bernard...");
Color myColor = new Color(10, 150, 80);
panel.setBackground(myColor);
label.setFont(new Font("Serif", Font.PLAIN, 25));
Dimension size = label.getPreferredSize();
Insets insets = label.getInsets();
label.setBounds(85+insets.left, 120+insets.top , size.width, size.height);
panel.add(label);
JMenuBar menu = new JMenuBar();
setJMenuBar(menu);
JMenu col = new JMenu("Collection");
menu.add(col);
JMenu help = new JMenu("Help");
menu.add(help);
Action loadAction = new AbstractAction("Load")//menu item exit goes here
{
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event)
{
JTextArea text = new JTextArea(10, 40);
JScrollPane scrol1 = new JScrollPane(text);
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
JScrollPane scrol2 = new JScrollPane(list);
JPanel panel2 = new JPanel(new BorderLayout());
panel2 = new JPanel(new GridLayout(1, 2 ));
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
}
};
JMenuItem load = new JMenuItem(loadAction);
col.add(load);
add(panel);
}
}
Call revalidate()/repaint() on your JFrame instance after adding the new panel:
JPanel panel2 = new JPanel(new BorderLayout());
// panel2 = new JPanel(new GridLayout(1, 2 ));//why this it will overwrite the above layout
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
revalidate();
repaint();
Also call pack() on you JFrame instance so all components are spaced by the layoutmanager. As said in a comment dont extend the JFrame class, create a variable of the frame and initiate all that you need on the frames instance, and dont set a layout to null, unless you love hard work :P
Alternatively as mentioned by mKorbel, a CardLayout may be more what you want, it will allow you to use a single JPanel and switch between others/new ones:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";
//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
//add card panel to frame
frame.add(cards);
//swap cards
CardLayout cl = (CardLayout)(cards.getLayout());//get layout of cards from card panel
cl.show(cards, TEXTPANEL);//show another card