JButton not appearing on JFrame - java

Following is the code in which the jbutton is not showing on the frame. I have also set visible to true. Even then the button doesn't appear.
class gui{
public static void main(String args[]){
layoutBorder lb=new layoutBorder("check");
}
}
class layoutBorder extends JFrame{
layoutBorder(String title){
super(title);
setLayout(null);
setSize(200, 200);
JButton jb=new JButton("JB");
add(jb);
setVisible(true);
}
}

Don't use a null layout!!!
Swing was designed to be used with layout managers.
Read the section from the Swing tutorial o Layout Managers for more information.
I suggest you download the working examples and play with them. The example will also show you how to better structure your code. Maybe start with the code from How to Use Buttons, which has a simple example that adds 3 buttons to a panel and then the panel to the frame.
Also, class names should start with an upper case character. Have you even seen a class in the API that doesn't??? Learn Java conventions and follow them.

camickr is right. Also, always use the AWT event dispatching thread when an application thread needs to update the GUI.
import javax.swing.*;
import java.awt.*;
import java.lang.*;
public class Gui {
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> {
MyFrame frame = new MyFrame("check");
});
}
}
class MyFrame extends JFrame {
MyFrame(String title){
super(title);
setLayout(new BorderLayout());
setSize(200, 200);
JButton jb = new JButton("JB");
add(jb);
setVisible(true);
}
}

If you want null layouts then you need to set sizes and position by yourself. Using the setLocation and setSize methods.
class gui{
public static void main(String args[]){
layoutBorder lb=new layoutBorder("check");
}
}
class layoutBorder extends JFrame{
layoutBorder(String title){
super(title);
setLayout(null);
setSize(200, 200);
JButton jb=new JButton("JB");
jb.setLocation(10, 10);
jb.setSize(40, 30);
add(jb);
setVisible(true);
}
}

Related

Why the textfield is taking whole screen of a window in Java awt [duplicate]

This question already has answers here:
Why this code's JTextArea occupies entire JFrame?
(2 answers)
Closed 6 years ago.
import java.awt.*;
public class myFrame extends Frame {
myFrame(){
TextField tf=new TextField(10);
setVisible(true);
setSize(400,400);
setTitle("myFrame");
setBackground(Color.red);
add(tf);
}
public static void main(String[] args){
myFrame f=new myFrame();
}
}
output image
A Frame uses BorderLayout by default, and if you add a component to it in a "default" manner (without BorderLayout constraints) it will be added to the BorderLayout.CENTER position, taking up the whole of the Frame.
Possible solutions include using a different layout such as FlowLayout or even better, nesting components such as Panels that use their own layouts and adding your TextField to it.
Side issue: why use the AWT GUI library when it is more than 2 generations out of date?
For example, with Swing
import java.awt.Dimension;
import javax.swing.*;
public class SwingExample extends JPanel {
private JTextField textField = new JTextField(10);
public SwingExample() {
// this is a JPanel that uses FlowLayout by default
setPreferredSize(new Dimension(400, 400));
add(textField);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui() {
SwingExample mainPanel = new SwingExample();
JFrame frame = new JFrame("SwingExample"); // uses borderlayout
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(mainPanel, BorderLayout.CENTER); // add jpanel to center position
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
}

Java GUI Help (JFrame, JButton, etc)

Ok so im new to programming GUIs in Java and I need some help on how to add buttons and Labels. I went around looking at an example and I figured it this was how it worked to basically add a button:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class GUI_Tests extends JFrame{
public static void main(String[] args){
private JButton button;
button = new JButton("pls work");
add(button);
}
}
Well that didnt work at all... Can someone show me how its done and give me some pointers?
You should note that a JFrame has a default BorderLayout which, if not specified, will add a component to a BorderLayout.CENTER position.
When adding components to JFrame, if a different Layout is not specified, then you want to set a component's position, like add(button, BorderLayout.SOUTH);
Also you should use a constructor. Something like this
public class GUI_Tests extends JFrame {
public GUI_Tests(){
JButton button = new JButton("Pls work");
JLabel label = new JLabel("Pls work");
add(button, BorderLayout.CENTER);
add(label, BorderLayout.SOUTH);
}
}
Also you need to remember to set the frame visible.
A simple running program would be something like this
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class GUI_Tests extends JFrame {
public GUI_Tests() {
JButton button = new JButton("Pls work");
JLabel label = new JLabel("Pls work");
add(button, BorderLayout.CENTER);
add(label, BorderLayout.WEST);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new GUI_Tests();
}
});
}
}
The main method may look somewhat crazy to you, but all it is doing is causing the program to run on the Event Dispatch Thread (EDT). I won't go into this too much as you are still a beginner.
What is going on in the run is that all I do is create an instance of me program, which extends JFrame. If I didn't extend JFrame, I would have to explicitly create a JFrame to run the program. All GUI programs need some top-level container to run.
Also you can see in the constructor, that when I added the button and label I set a layout position
add(button, BorderLayout.CENTER);
add(label, BorderLayout.SOUTH);
as I stated earlier, when using a JFrame without specifying a different layout, you should use position with the default `BorderLayout. Other possible positions are
BorderLayout.EAST
BorderLayout.WEST
BorderLayout.CENTER
BorderLayout.NORTH
BorderLayout.SOUTH
Take a look at [Laying Out Components Within a Container]Laying Out Components Within a Container)
Also, noticed I used pack(). What this does is make the frame the perfect with for the preferrsed sizes of the components. It is preferred to pack() rather then setSize() of a frame.
setDefaultCloseOperation(EXIT_ON_CLOSE); makes it so that when x out the frame, the program shuts down.
setLocationRelativeTo(null); set the frame's location in the center of the screen
setVisible(true); makes the frame visible. This should always be called to make the frame visible on start of the program.
Please have a look at the Swing tutorials
You are supposed to add your JButton to a JFrame, but it seems to me that you haven't even created a JFrame yet. You should first create an instance of GUI_Tests, then use the JFrame#add method with your JButton. For example:
public class GUI_Tests extends JFrame {
public GUI_Tests() {
super("My first Swing frame!");
this.setPreferredSize(new Dimension(640, 480));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create your GUI here
this.add(new JButton("Click on me :)"));
this.setVisible(true);
}
}
Actually, I wouldn't be mean to you, but I think you tried to go too fast: in my opinion, you should start by following some tutorial on how to deal with Swing :)
public class GUI_Tests extends JFrame {
private JButton button;
public GUI_Tests() {
setTitle("Title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // so that the application properly closes when you click close
button = new JButton("pls work");
add(button);
pack(); // resize the frame to its contents
setLocationRelativeTo(null); // center the frame on the screen
}
public static void main(String args[]) {
// properly start a swing application
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GUI_Tests gui = new GUI_Tests();
gui.setVisible(true); // set the frame visible
}
});
}
}
hope this helps you understand it a bit more. i didn't use any layouts in this code as its just a simple example, however, i highly recommend you to read on built-in layouts in swing and how to use them.
Here's one good start
You need to add your button to a JFrame The basic flow should look something like this:
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class GUITests extends JFrame{
public GUITests() {
setTitle("Simple example");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JButton button = new JButton("pls work");
add(button);
pack();
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
GUITests ex = new GUITests();
ex.setVisible(true);
}
});
}
}
The GUITests class extends the JFrame class so you can call all the methods that are visible on the JFrame class. In the main method It's just some boiler plate code that calls your constructor for you so that you can see your basic example.
Check out the tutorials here: http://zetcode.com/tutorials/javaswingtutorial/firstprograms/
type
setVisible( true );
setSize( 500 , 500 );
and I think you'll see something. Also get rid of private in the statement private JButton button But you should really put your code in the constructor of the GUI_Tests:
import javax.swing.*;
public class GUI_Tests extends JFrame {
public GUI_Tests() {
JButton button = new JButton( "Hello World" );
add( button );
setVisible( true );
setSize( 500 , 500 );
}
final public static void main( String[] args ) {
GUI_Tests tests = new GUI_Tests();
}
}
Check out the Java tutorial for more help, possibly here: http://docs.oracle.com/javase/tutorial/uiswing/start/index.html

How can I append a JTextArea from a method that doesn't contain the JTextArea?

I'm making some test code to practice OOP, and I want to append a JTextArea from the "writeToArea" to the "initialize" method where the JTextArea is defined and initialized. I already tried to directly call the "output" variable, but this returns an "output cannot be resolved" error. I want so that whenever I call the "writeToArea" method in the main class, I'll be able to add lines to the "output" JTextArea in the "initialize" method.
Here's the main class:
public class Pangea {
public static void main(String[] args) {
UI.initialize();
UI.writeToArea();
}
}
Here's the initialize class:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class UI {
static void initialize() {
System.out.println("Initializing GUI.");
JFrame frame = new JFrame();
Font myFont = new Font("Courier", Font.BOLD, 14);
JTextField input = new JTextField("");
JTextArea output = new JTextArea("Initiated Succesfully.");
output.setWrapStyleWord(true);
output.setLineWrap(true);
input.setFont(myFont);
output.setFont(myFont);
input.setForeground(Color.WHITE);
output.setForeground(Color.WHITE);
input.setBackground(Color.BLACK);
input.setCaretColor(Color.WHITE);
output.setBackground(Color.BLACK);
output.setEditable(false);
JScrollPane jp = new JScrollPane(output);
frame.setTitle("PANGEA RPG [0.01 ALPHA][WIP]");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(input, BorderLayout.SOUTH);
frame.add(jp, BorderLayout.CENTER);
frame.pack();
frame.setSize(800, 500);
frame.setVisible(true);
System.out.println("GUI Initialized.");
}
static void writeToArea() {
System.out.println("\"writeToArea\" running.");
output.append("Hello!");
System.out.println("\"writeToArea\" finished.");
}
}
I've tried to do something similar to this: Updating jtextarea from another class but it didn't work. If anyone has any suggestions I'd be very thankful.
The main error in your code is the lack of OOP design. Making all static is poor design.
Also swing is event based, so you should append text to the textArea when an event happens. See the example i write for you.
public class UI {
private JPanel panel;
private JTextArea output;
public UI(){
initialize();
}
private void initialize() {
panel = new JPanel();
Font myFont = new Font("Courier", Font.BOLD, 14);
final JTextField input = new JTextField(""); // must be declared final cause you use it in anonymous class, you can make it instance variable if you want to as textArea
//add an actionListener then when you press enter this will write to textArea
input.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent evt){
writeToArea(input.getText());
}
});
output = new JTextArea("Initiated Succesfully",50,100);// let the component determinate its preferred size.
output.setWrapStyleWord(true);
output.setLineWrap(true);
input.setFont(myFont);
output.setFont(myFont);
input.setForeground(Color.WHITE);
output.setForeground(Color.WHITE);
input.setBackground(Color.BLACK);
input.setCaretColor(Color.WHITE);
output.setBackground(Color.BLACK);
output.setEditable(false);
JScrollPane jp = new JScrollPane(output);
panel.setLayout(new BorderLayout());
panel.add(input, BorderLayout.SOUTH);
panel.add(jp, BorderLayout.CENTER);
}
private void writeToArea(String something) {
System.out.println("\"writeToArea\" running.");
output.append(something);
System.out.println("\"writeToArea\" finished.");
}
public JPanel getPanel(){
return panel;
}
}
And in your client code
public class Pangea {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
createAndShowGUI();
}
});
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
System.out.println("Initializing GUI.");
JFrame frame = new JFrame();
frame.setTitle("PANGEA RPG [0.01 ALPHA][WIP]");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add contents to the window.
frame.add(new UI().getPanel());
frame.pack();//sizes the frame
frame.setVisible(true);
System.out.println("GUI Initialized.");
}
}
Here you have a tutorial with better examples than this How to Use Text Areas
I remove your setSize and use pack()
The pack method sizes the frame so that all its contents are at or
above their preferred sizes. An alternative to pack is
to establish a frame size explicitly by calling setSize or setBounds
(which also sets the frame location). In general, using pack is
preferable to calling setSize, since pack leaves the frame layout
manager in charge of the frame size, and layout managers are good at
adjusting to platform dependencies and other factors that affect
component size.
Read the section from the Swing tutorial on How to Use Text Areas. It will show you how to better structure your code so that you don't use static methods and variables everywhere.
Once you have a panel that has a reference to the text area you can add methods that allow you to update the text area on the panel.

BorderLayout - child component remains visible after adding another component

I try to do the following thing:
Add a component to a JFrame with a BorderLayout
Add another component to the JFrame
I would expect the new component to 'overwrite' the old component, since I'm using a BorderLayout. This works if I overwrite the old component before I call pack(). Now if I add the 2nd component after I call pack(), both components remain visible. Example:
public class Test extends JFrame{
public Test(){
setLayout(new BorderLayout());
add(new JLabel("Quite a long text"));
setVisible(true);
pack();
add(new JLabel("Another text"));
}
}
Result:
public class Test extends JFrame{
public Test(){
setLayout(new BorderLayout());
add(new JLabel("Quite a long text"));
setVisible(true);
add(new JLabel("Another text"));
pack();
}
}
Result:
I tried adding validate(); and repaint();, but that wouldn't help. What's going wrong here?
You are calling things that affect the UI after setViisble() is called -- a Swing no-no. Put things that affect the UI into an invokeLater call; look it up.
While you're at it, I think you're still supposed to get the content pane from the frame for adding components... And I don't think creating things in the constructor is a good idea.
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
public class SwingTest extends JFrame
{
public void createUI()
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
SwingUtilities.invokeLater(
new Runnable()
{
public void run()
{
getContentPane().setLayout(new BorderLayout());
getContentPane().add(new JLabel("Quite a long text"), BorderLayout.CENTER);
getContentPane().add(new JLabel("Another text"), BorderLayout.CENTER);
pack();
setVisible(true);
}
}
);
}
public static void main(String ... args)
{
SwingTest st = new SwingTest();
st.createUI();
}
}

Why does my JFrame stay empty, if I subclass JPanel and JFrame?

I'm trying to write custom JFrame and JPanel for my Java application. Currently, I just want to have a JPanel with a start button in the very middle of the screen. So, here's the code I have:
package gui;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
#SuppressWarnings("serial")
public class SubitizingFrame extends JFrame implements KeyListener {
public SubitizingFrame() {
super("Subitizing");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
add(new LaunchPanel());
pack();
setVisible(true);
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_F5)
System.out.println("F5 pressed");
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
and here is my panel:
package gui;
import instructions.Settings;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class LaunchPanel extends JPanel implements ActionListener {
private JButton startButton;
public LaunchPanel() {
int width = Settings.getScreenSizeX(), height = Settings.getScreenSizeY();
setPreferredSize(new Dimension(width, height));
setLayout(null);
startButton = new JButton("Start");
startButton.setLocation((width/2) - (startButton.getWidth()/2), (height/2) - (startButton.getHeight()/2));
add(startButton);
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
}
But when the application launches, I don't see anything. Just a big gray screen.
Do not use a null layout. If you simply use the default layout manager of JPanel (i.e. FlowLayout), the JButton with "automagically" be placed in the center. Also, in order to place the JFrame in the middle of the screen, invoke setLocationRelativeTo(null).
Since it's hard to tell what you mean by "screen", this example shows how you center a JButton in a JPanel in a JFrame, that is then centered on the monitor.
public final class CenterComponentsDemo {
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI(){
final JFrame frame = new JFrame("Center Components Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ButtonPane());
frame.setSize(new Dimension(300, 100)); // Done for demo
//frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class ButtonPane extends JPanel{
public ButtonPane(){
super();
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.PINK);
final JButton button = new JButton("Start");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
add(Box.createVerticalGlue());
add(button);
add(Box.createVerticalGlue());
}
}
}
Recommendations:
Avoid using null layout as this makes your app difficult to upgrade and maintain and makes it potentially very ugly or even non-usable on boxes with different OS's or screen resolutions.
If you have your JPanel use a GridBagLayout and add a single component to it without using GridBagConstraints, it will be placed in the center of the JPanel.
You almost never have to or should extend JFrame and only infrequently need to extend JPanel. Usually it's better to enhance your GUI classes through composition rather than inheritance.
Avoid having your "view" or gui classes implement your listener interfaces. This is OK for "toy" programs, but as soon as your application gains any appreciable size or complexity, this gets hard to maintain.
If you don't use any LayoutManager (which btw you probably should), then you'll need to set the size of the panel as well (along with its position).
Although we strongly recommend that you use layout managers, you can perform layout without them. By setting a container's layout property to null, you make the container use no layout manager. With this strategy, called absolute positioning, you must specify the size and position of every component within that container. One drawback of absolute positioning is that it does not adjust well when the top-level container is resized. It also does not adjust well to differences between users and systems, such as different font sizes and locales.
From: http://download.oracle.com/javase/tutorial/uiswing/layout/using.html
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class LaunchPanel extends JPanel {
private JButton startButton;
public LaunchPanel() {
int width = 200, height = 100;
setPreferredSize(new Dimension(width, height));
setLayout(new GridBagLayout());
startButton = new JButton("Start");
add(startButton);
setBorder( new LineBorder(Color.RED, 2));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null, new LaunchPanel());
}
});
}
}
addKeyListener(this);
Don't use KeyListeners. Swing was designed to be used with Key Bindings. Read the section from the Swing tutorial on How to Use Key Bindings for more information.
The tutorial also has a section on Using Layout Manager which you should read. You should not create GUI's with a null layout.

Categories

Resources