I'm a geek and I have started learning Java this year. I have a problem at next code: the program is running but, unfortunately, don't want to stop and to show my window with buttons. I don't understand, way? Please, give me some ideas, I have tried all, but in vain!
package arbitru;
import java.awt.FlowLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
public class TogleButon {
public static void main(String[] args) {
JFrame window=new JFrame("Name");
JPanel Panou=(JPanel) window.getContentPane();
Panou.setLayout(new FlowLayout());
JToggleButton button1=new JToggleButton("Button 1", true);
Panou.add(button1);
JToggleButton button2=new JToggleButton("Button 2", false);
Panou.add(button2);
JToggleButton button3=new JToggleButton("Button 3", false);
Panou.add(button3);
ButtonGroup Group_button=new ButtonGroup();
Group_button.add(button1);
Group_button.add(button2);
Group_button.add(button3);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
}
A quick fix for your problem is to call pack() before calling setVisible().
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.pack(); // Add this line.
window.setVisible(true);
The method pack() will size the JFrame such that it is big enough to display its contained components at their preferred sizes.
Nonetheless you should be aware that your code is not good. You shouldn't construct your GUI in the main() method. For learning Swing I recommend Creating a GUI With JFC/Swing
Related
I need to create a 8x8 grid where each tile is a JButton using two nested for loops. I’ve tried and tried but can’t get it done.
Needed for a game of Reversi (Othello) assignment.
Oracle has a nifty tutorial, Creating a GUI With JFC/Swing, that will take you through the steps of creating a Swing GUI. Skip the Netbeans section.
Here's a GUI with an 8 x 8 grid of JButtons.
The first thing I did was make a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
I created a JFrame. The JFrame methods must be called in a specific order. This is the order I use for most of my Swing applications.
I created a JPanel. The JPanel uses a GridLayout to lay out the 64 JButtons I created.
Swing components should always be constructed in a JPanel. A JFrame has a default BorderLayout that allows you to place up to nine JPanels on the JFrame. Even though it's possible, you should never place any Swing components other than JPanels or JScrollPanes directly on a JFrame.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class OthelloGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new OthelloGUI());
}
#Override
public void run() {
JFrame frame = new JFrame("Othello GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridLayout(0, 8));
panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
for (int index = 0; index < 64; index++) {
JButton button = new JButton();
button.setPreferredSize(new Dimension(64, 64));
panel.add(button);
}
return panel;
}
}
I know this question has been asked a lot and I have done my research but still can not find anything. Below is proof of this before anyone gets upset:
I found this link:
https://coderanch.com/t/563764/java/Blank-Frame-Panel
and this:
Adding panels to frame, but not showing when app is run
and this:
Why shouldn't I call setVisible(true) before adding components?
and this:
JPanel not showing in JFrame?
But the first question says use repaint which I tried with no fix and the second and third to last questions talk about putting setVisible after components added which I have.
The last one talks about making the users JPanelArt a extension (done so) of JPanel instead of JFrame and not to make a frame in a frame constructor (also have not done)
When ever I run this I just get a blank frame, as if the panel was never added in.
I apologise if I have missed something in those links. Anyway below is my classes:
GUI.java (extends JFrame)
package javaapplication2;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUI extends JFrame{
public GUI(String name) {
super(name);
getContentPane().setLayout(null);
JPanel myPanel1 = new GUIPanel();
myPanel1.setLocation(20, 20);
getContentPane().add(myPanel1);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setResizable(true);
}
public static void main(String[] args) {
JFrame frame = new GUI("Game");
frame.setVisible(true);
}
}
GUIPanel.java (extends JPanel)
package javaapplication2;
import java.awt.*;
import javax.swing.*;
public class GUIPanel extends JPanel {
JButton start;
JButton inspect1;
JButton inspect2;
JButton inspect3;
JButton suspect;
public GUIPanel() {
setLayout(new BorderLayout());
start = new JButton("Start Game");
inspect1 = new JButton("Inspect 1");
inspect2 = new JButton("Inspect 2");
inspect3 = new JButton("Inspect 3");
suspect = new JButton("Choose Suspect");
add(start, BorderLayout.WEST);
add(inspect1, BorderLayout.WEST);
add(inspect2, BorderLayout.WEST);
add(inspect3, BorderLayout.WEST);
add(suspect, BorderLayout.WEST);
}
}
I know it is very simple, but that is because I am following a tutorial from my lecturer to get the hang of things as I previously used a GUI builder which someone in this community pointed out to me is not good to start with (very correct!)
The issue lies in your GUI class when you call getContentPane().setLayout(null). Because of this method call, your JFrame is not displaying anything. If you remove it, your elements should show up.
I also noticed that you were setting each JButton to have a constraint of BorderLayout.WEST. This will most likely put your JButtons on top of each other and render only one of them.
Recently every single one of my apps that extends JFrame fails to actually show the frame. The program will run and then will terminate after about 8 seconds without ever showing anything and without an error message. This happens for all the programs I've made in the past as well as any new programs.
For testing purposes I am using the basic example from the oracle documentations.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class test extends JFrame{
public static void main(String[] args){
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
JLabel emptyLabel = new JLabel();
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
}
}
I am using eclipse and I've already tried switching workplaces.
I've looked at existing threads and found nothing that wasn't due to coding errors.
How can i solve this?
EDIT: The program doesn't output anything from System.out.println() after this line:
JFrame frame = new JFrame("FrameDemo");
It outputs anything before that.
Alright so I checked your code and it works.
First things first, your JLabel isn't visible if it doesn't have anything in it.
pack();
//basically CRUSHES the entire frame if it doesn't have objects to collapse on.
Also, if you don't want to put anything in your JLabel, don't pack it yet. Just set it to a certain size with
frame.setSize(width,height);
It only shows nothing because you collapsed it without putting anything in the JLabel. I hope I answered your question basically this is what you want
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class test extends JFrame{
public static void main(String[] args){
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
JLabel emptyLabel = new JLabel("BLAHBLAHBHALBAHLKKDJF");
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
}
}
Or you could just set size with
frame.setSize(width,height);
Have fun!
First of all, this is a more specific question than it seems to be. To start off: I am currently doing a small application with a rather small GUI, so I decided to make a GUI class, and initialize my whole GUI in this constructor.
This would look like this:
public class GUI extends JFrame{
public GUI{
//Initialize GUI here, including its Frames, Panels, Buttons etc.
}
}
How can I now access the GUIs frame etc. from an external class? If I would create an object of the GUI class, I would simply duplicate my GUI window. I did not come across any other ideas than making the frame, panel and so on static.
I'm somewhat lost right now. Also I'm pretty sure that I am not thinking the right way into this case, but I need someone to point me to the right direction. If someone could help me out, I would be very thankful.
First of all, using static is the worst solution possible, even if your GUI class is a singleton (buf if it is, at least it will work fine).
Why don't you simply create getters and/or setters ? And finally, it is usually not normal that external classes need to access the components of another graphic class. You should wonder if your design is the most fitted for your needs.
Here's a simple GUI to change the background color of a JPanel with a JButton. Generally, this is how you construct a Swing GUI.
package com.ggl.testing;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ChangeDemo implements Runnable {
private boolean isYellow;
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new ChangeDemo());
}
#Override
public void run() {
frame = new JFrame("Change Background Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
JPanel namePanel = new JPanel();
JLabel nameLabel = new JLabel(
"Click the button to change the background color");
nameLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
namePanel.add(nameLabel);
mainPanel.add(namePanel);
final JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout());
buttonPanel.setBackground(Color.YELLOW);
isYellow = true;
JButton changeButton = new JButton("Change Color");
changeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
isYellow = !isYellow;
if (isYellow) buttonPanel.setBackground(Color.YELLOW);
else buttonPanel.setBackground(Color.RED);
}
});
buttonPanel.add(changeButton);
mainPanel.add(buttonPanel);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}
You don't access the Swing components of the GUI from other classes. You create other classes to hold the values of the GUI.
Generally, you use the model / view / controller pattern to construct a Swing GUI. That way, you can focus on one part of the GUI at a time.
Take a look at my article, Java Swing File Browser, to see how the MVC pattern works with a typical Swing GUI.
You don't need to make it static or to create a new JFrame object every time.
Have a look at this simple code :
class UseJFrame {
public static void main(String...args) {
Scanner sc = new Scanner(System.in);
JFrame frame = new GUI();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
System.out.println("Press E to exit");
String ip;
while(true) {
System.out.println("Show GUI (Y/N/E)? : ");
ip = sc.nextLine();
if(ip.equalsIgnoreCase("y") {
frame.setVisible(true);
} else if(ip.equalsIgnoreCase("n") {
frame.setVisible(false);
} else { // E or any other input
frame.dispose();
}
}
}
}
Note : Don't make GUI visible through constructor or it will show window at the very starting of creation of JFrame object.
If you want to use the same JFrame object at other places too then pool architecture would be better approach.
so I have this problem. I wrote this code in Java Eclipse SDK 4.2.1. I haven't wrote it all here, actionPerformed method is irrelevant now and it is called from Main once. The problem is sometimes when I run it, one of the components just fills the whole window and overlaps all others. I tried changing sizes by random numbers for example from 400 to 350 and sometimes it worked and then it broke again. I'm probably missing something, I just don't know what. I searched other forums, but found nothing about it.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Window extends JFrame implements ActionListener
{
JTextField field1;
JTextField field2;
public Window()
{
super("Main Window");
setVisible(true);
setSize(500, 500);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Initialize();
}
private void Initialize()
{
field1 = new JTextField();
field2 = new JTextField();
field1.setBounds(0, 0, 400, 100);
field2.setBounds(0,100,400,100);
add(field1);
add(field2);
field1.setBackground(Color.PINK);
field1.setForeground(Color.RED);
field2.setBackground(Color.PINK);
field2.setForeground(Color.RED);
JButton button = new JButton("Create");
button.setBounds(0, 200, 400, 100);
add(button);
button.setBackground(Color.BLACK);
button.setForeground(Color.YELLOW);
button.addActionListener(this);
}
Your problem is that your code does not respect the layout manager being used as you're trying to add components as if the layout being used were null when in fact it isn't. The solution is to read up on and learn about layout managers, and use them; this includes avoiding calling setBounds(...). Note that a JFrame's contentPane uses BorderLayout by default. This information should help you get started. Also note that a wrong solution is to use a null layout. So if anyone suggests this, I urge you to ignore them.