Java button is working strangely - java

I am using Swing to build a GUI in Java. The code to make the button and add it is like this:
//Create a button
JButton exitButton = new JButton("Exit");
exitButton.setSize(90, 40);
exitButton.setLocation(800, 450);
exitButton.setVisible(true);
//Adding components
window.getContentPane().add(exitButton);
When I run the app, the button appears in the whole window, sometimes appears as its intended and sometimes doesn't come. Is this some sort of java bug or a prob with my sdk. In case you wish to know what sort of window it is,
//Create a window
JFrame window = new JFrame("First Window");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
window.setVisible(true);
window.setSize(1000, 550);
window.setLocation(150, 150);
It's all within static void main. BTW, how I get the button to close the window through System.exit(0); (I am a beginner and this is my first self-written GUI)

You need a layout. See A Visual Guide to Layout Managers.
Also please check my tutorials here.

I got this sample code. This might be helpful Simple swing buttons
package com.ack.gui.swing.simple;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
public class SimpleSwingButtons extends JFrame {
public static void main( String[] argv ) {
SimpleSwingButtons myExample = new SimpleSwingButtons( "Simple Swing Buttons" );
}
public SimpleSwingButtons( String title ) {
super( title );
setSize( 150, 150 );
addWindowListener( new WindowAdapter() {
public void windowClosing( WindowEvent we ) {
dispose();
System.exit( 0 );
}
} );
init();
setVisible( true );
}
private void init() {
JPanel my_panel = new JPanel();
my_panel.setLayout( new GridLayout( 3, 3 ) );
for( int i = 1; i < 10; i++ ) {
ImageIcon icon = new ImageIcon( i + ".gif" );
JButton jb = new JButton( icon );
jb.setToolTipText( i + ".gif" );
my_panel.add( jb );
}
getContentPane().add( my_panel );
my_panel.setBorder( BorderFactory.createEtchedBorder() );
}
}
courtesy Java.happycodings

You must check your layout, if you want to use custom position for your components, set Layout as null and use the setBounds(x,y,weight,height) method.
JFrame window = new JFrame("First Window");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)
window.setLayout(null);
JButton exitButton = new JButton("Exit");
exitButton.setBounds(15,45,150,30);//This is just an example
exitButton.setVisible(true);
Best regards.

Related

Java Swing Label not appearing

This is my first time learning Java Swing and I had a label and setLocation wasn't working. Someone told me it's because you have to set the layout to null, otherwise they're set to default locations and sizes. So I did, and now my label isn't appearing
import java.util.*;
import javax.swing.*;
public class School {
private ArrayList <String> Usernames = new ArrayList <> ();
private ArrayList <String> Passwords = new ArrayList <> ();
public void registerUser(){
JFrame Register = new JFrame("Register");
JLabel Username = new JLabel("Username: ");
Username.setBounds(50, 50, 100, 30);
Register.add(Username);
Register.setVisible(true);
Register.setSize(500, 500);
Register.setLayout(null);
Register.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main (String [] args){
School example = new School();
example.registerUser();
}
}
Here's a simple example where I corrected a few issues.
I'm using the default layouts, not null. The defaults work well if you learn how to use them.
I use a JPanel instead of adding components directly to the JFrame. JFrames actually use a rather confusing layout, it's best to just put stuff in a panel which makes the layout more intuitive.
I'm using vertical boxes and horizontal boxes and nesting them (putting one inside the other). When I first started this was an easy way to make simple formatted layouts.
I put the labels and text fields in a loop so you could see how to make several components in a loop and still lay them out.
I changed several of your variable names to conform to the Java coding conventions (use lower case for local variables and fields).
I added a more conventional sequence for displaying a window for the first time.
I also kicked off your Swing code on the Event Dispatch Thread. You should do this for all Swing code.
Lightly tested:
package stackoverflow;
import java.util.*;
import javax.swing.*;
public class BasicWindow {
private ArrayList<String> userNames = new ArrayList<>();
private ArrayList<String> passwords = new ArrayList<>();
public void registerUser() {
JFrame register = new JFrame( "Register" );
JPanel panel = new JPanel();
Box vbox = Box.createVerticalBox();
for( int i = 0; i < 4; i++ ) {
Box hbox = Box.createHorizontalBox();
JLabel username = new JLabel( "Username: " );
hbox.add( username );
JTextField input = new JTextField( 25 );
hbox.add( input );
vbox.add( hbox );
}
panel.add( vbox );
register.add( panel );
register.setSize( 500, 500 );
register.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
register.setLocationRelativeTo( null ); // center on screen
register.setVisible( true );
}
public static void main( String[] args ) {
SwingUtilities.invokeLater( new Runnable() {
#Override
public void run() {
BasicWindow example = new BasicWindow();
example.registerUser();
}
});
}
}

setDefaultButton - Focus Loss

I have found that when a modal JDialog launches a second modal JDialog, and when that second JDialog is disposed, the first JDialog seems to (mostly) ignore the keyboard.
I have included a sample program to demonstrate the issue. On running the code, I should be able to hit the space bar (the button in the main JFrame has focus) and the first JDialog is launched, containing a button (also with focus).
I hit the space bar and the second JDialog is launched. Hitting enter, the second JDialog disposes.
Hitting space bar on the first JDialog results in no response. Alt- F4 will close the first JDialog, so the keyboard is not completely disconnected.
Repeating the above procedure using the mouse only, the issue does not occur.
The background to all of this is I wanted to set the default button on a dialog (in which the user enters some text and other data). If I comment out the setDefaultButton in the second JDialog and now use TAB to move around, the issue does not occur.
In short, I want to be able to set a default button on a JDialog (so I can hit the enter key), but at the same time, I want default focus on a JTextField.
I am on Ubuntu 13.10 using the OpenJDK (64 bit). I have found this happens regardless of using the GTK+ look and feel or the metal look and feel (that is, not setting any look and feel).
I cannot reproduce on Windows XP (using Oracle Java 32 bit).
On reading a few posts, it seems Linux and Java have a few focus problems and so I'm not sure if this is a programming error on my part or I've stumbled upon a Linux/Java issue.
Any ideas please?
Below is example code which reproduces the issue.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class Test extends JFrame
{
public Test()
{
JButton button = new JButton( "Test" );
button.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent actionEvent ) { new Test1( Test.this ); } } );
JPanel panel = new JPanel();
panel.add( button );
getContentPane().add( panel );
pack();
setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
setVisible( true );
}
protected class Test1 extends JDialog
{
public Test1( JFrame owner )
{
super( owner );
JButton button = new JButton( "1" );
button.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent actionEvent ) { new Test2( Test1.this ); } } );
JPanel panel = new JPanel();
panel.add( button );
getContentPane().add( panel );
pack();
setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
setLocationRelativeTo( null );
setModalityType( ModalityType.APPLICATION_MODAL );
setVisible( true );
}
}
protected class Test2 extends JDialog
{
public Test2( JDialog owner )
{
super( owner );
JTextField textField = new JTextField();
JButton button = new JButton( "2" );
getRootPane().setDefaultButton( button );
button.addActionListener
(
new ActionListener()
{
public void actionPerformed( ActionEvent actionEvent )
{
// Test2.this.getRootPane().setDefaultButton( null ); // Makes no difference!
Test2.this.dispose();
}
}
);
JPanel panel = new JPanel( new BorderLayout() );
panel.add( textField, BorderLayout.CENTER );
panel.add( button, BorderLayout.SOUTH );
getContentPane().add( panel );
pack();
setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
setLocationRelativeTo( null );
setModalityType( ModalityType.APPLICATION_MODAL );
setVisible( true );
}
}
public static void main( String[] args )
{
new Test();
}
}

Java Popup Button

Note: You may have to compile and run my example to fully understand my question. If this is not kosher, I apologize in advance.
I am trying to create a Swing control that is based on a JToggleButton and a JPopupMenu.
The toggle button is selected iff the popup menu is visible, and the toggle button is deselected iff the popup menu is not visible. Thus, the behavior is similar to a JComboBox, except that the popup can contain arbitrary components.
The code that follows is an example of how I would create the control (except that it would be in its own class... something like a JPopupToggleButton). Unfortunately, it exhibits different behavior under different look and feels (I have tested it with Metal and Nimbus).
The code as posted here behaves as expected in Metal, but not in Nimbus. When using Nimbus, just show and hide the popup by repeatedly clicking the toggle button and you will see what I mean.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
public class PopupButtonExample extends JFrame
{
public static void main( String[] args )
{
java.awt.EventQueue.invokeLater( new Runnable()
{
#Override
public void run()
{
PopupButtonExample example = new PopupButtonExample();
example.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
example.setVisible( true );
}
});
}
public PopupButtonExample()
{
super( "Components in Popup" );
JPanel popupPanel = new JPanel();
popupPanel.setLayout( new BorderLayout() );
popupPanel.add( new JLabel( "This popup has components" ),
BorderLayout.NORTH );
popupPanel.add( new JTextArea( "Some text", 15, 20 ),
BorderLayout.CENTER );
popupPanel.add( new JSlider(), BorderLayout.SOUTH );
final JPopupMenu popupMenu = new JPopupMenu();
popupMenu.add( popupPanel );
final JToggleButton popupButton = new JToggleButton( "Show Popup" );
popupButton.addActionListener( new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if( popupButton.isSelected() )
popupMenu.show( popupButton, 0, popupButton.getHeight() );
}
});
popupMenu.addPopupMenuListener( new PopupMenuListener()
{
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent pme) {}
#Override
public void popupMenuCanceled(PopupMenuEvent pme) {}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent pme) {
Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
Point componentLoc = popupButton.getLocationOnScreen();
mouseLoc.x -= componentLoc.x;
mouseLoc.y -= componentLoc.y;
if( !popupButton.contains( mouseLoc ) )
popupButton.setSelected( false );
}
});
JPanel toolBarPanel = new JPanel();
toolBarPanel.add( popupButton );
JToolBar toolBar = new JToolBar();
toolBar.add( toolBarPanel );
setLayout( new BorderLayout() );
add( toolBar, BorderLayout.PAGE_START );
setPreferredSize( new Dimension( 640, 480 ) );
pack();
}
}
Commeting out the following lines makes the code behave as expected in Nimbus, but not in Metal. Again, just keep clicking the toggle button to see what I mean.
// Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
// Point componentLoc = popupButton.getLocationOnScreen();
// mouseLoc.x -= componentLoc.x;
// mouseLoc.y -= componentLoc.y;
// if( !popupButton.contains( mouseLoc ) )
So here are my two questions:
(1) In Nimbus, why does the click that hides the popup panel not get passed to the toggle button, as it does with Metal?
(2) How can I solve this problem so that it works with all look and feels?
Nimbus is too buggy (and development ended somewhere in the middle) I see that you need three mouse click to the JToggleButton in compare with Metal
every standard L&F have got own specific issues, especially SystemLookAndFeel
use JWindow rather that JPopup, because with JPopup there are another Bugs too e.g. JPopup with JCombobox
After some investigation, I found the cause for the difference between Nimbus and Metal. The following flag is used (at least by BasicPopupMenuUI) to control the consumption of events when a popup is closed:
UIManager.getBoolean( "PopupMenu.consumeEventOnClose" );
When using Nimbus, this returns true. When using Metal, this returns false. Thus, the method popupMenuWillBecomeInvisible should be defined as follows:
if( UIManager.getBoolean( "PopupMenu.consumeEventOnClose" ) )
{
popupButton.setSelected( false );
}
else
{
Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
Point componentLoc = popupButton.getLocationOnScreen();
mouseLoc.x -= componentLoc.x;
mouseLoc.y -= componentLoc.y;
if( !popupButton.contains( mouseLoc ) )
{
popupButton.setSelected( false );
}
}

Java Swing design

I have a question regarding coding a Swing UI. If I want to make a software with some option e.g. on the first Frame I have three buttons (New, Option, Exit).
Now if a user clicks the new button, I want to change the entire content in the Frame to something else. I know I have to use addActionListener to that button. But my question is how to change the contents in the frame. Creating new Frames and then use setVisible() isn't an option for me.
And to use frame.remove() all the objects seems awkward if it is several things that needs to be removed. Or is it the right way?
Look into the Card Layout. I would also probably use menu items instead of buttons.
CardLayout is indeed the better choice in this case; but, when the occasion demands, a Component may be removed from a Container using either the remove() or removeAll() method. Afterward, the essential step is to invoke the [validate()](http://java.sun.com/javase/6/docs/api/java/awt/Container.html#validate()) method to lay out the container's subcomponents again. Oscar Reyes' example uses the Frame's [pack()](http://java.sun.com/javase/6/docs/api/java/awt/Window.html#pack()) method, inherited from Window, to achieve this effect. In this example, the resetGame() method reconstructs the display panel in a similar way.
You may use frame.remove()
The difference is that you may remove a whole panel instead of removing "several" things, and you just replace it with a new panel
frame.add( mainPanel );
...
// in the action listener
frame.remove( mainPanel );
frame.add( theNewPage );
The point is, you don't have to be afraid of removing awkwardly things in the main frame, for you have to place all those things into a single panel and then just change panels.
UPDATE
I've made the code needed to test what I'm talking about.
Here's a running sample:
alt text http://img190.imageshack.us/img190/5206/capturadepantalla200912p.png
later
alt text http://img301.imageshack.us/img301/1368/capturadepantalla200912n.png
Here's the running sample:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ChangePage {
JComponent mainPage;
JComponent newPage;
JFrame frame;
public static void main( String [] args ) {
ChangePage changePageDemo = new ChangePage();
changePageDemo.show();
}
private void show(){
frame = new JFrame("Demo");
frame.add( getMainPage() );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
private JComponent getMainPage() {
if( this.mainPage != null ) {
return this.mainPage;
}
this.mainPage = new JPanel(new BorderLayout());
mainPage.add( new JLabel("Choose an option") );
mainPage.add( new JPanel(){{
add( new JButton("New"){{
addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ){
SwingUtilities.invokeLater( new Runnable(){
public void run(){
frame.remove( getMainPage() );
frame.add( getNewPage() );
//frame.setContentPane( getNewPage() );
frame.pack();
}
});
}
});
}});
add( new JButton("Options"));
add( new JButton("Exit"));
}}, BorderLayout.SOUTH );
return this.mainPage;
}
private JComponent getNewPage() {
if( newPage != null ) {
return newPage;
}
this.newPage = new JPanel();
this.newPage.add( new JLabel("<html>This is the \"new\" page.<br> Do you like it?<br></html>"));
this.newPage.add( new JButton("Return"){{
addActionListener( new ActionListener(){
public void actionPerformed( ActionEvent e ){
SwingUtilities.invokeLater( new Runnable(){
public void run(){
frame.remove( getNewPage() );
frame.add( getMainPage() );
//frame.setContentPane( getMainPage() );
frame.pack();
}
});
}
});
}});
return this.newPage;
}
}
Alternatively you may use setContentPane :)
The easiest way is to use a Tabbed Pane.

In swing GUI how to show a JPanel as maximized when the user clicks a button?

I want to maximize a JPanel inside a JFrame when the user clicks a button.What is the best way to achieve this.The view and the data model should be in sync in both the panels,that is the panel which in the JFrame and the maximized one.Please suggest me some solution.
my requirement is: i have a JFrame with 4 JPanels named as
JPanelA,JPanelB,JPanelC,JPanelD
Here the JPanelD contains a JList and
a button below it say "MAXIMIZE
PANEL" button . JList has a JTree
with in it . Sometimes the JList may
have huge set of data and it is not
visible to the user clearly.
So he need to maximize this JPanelD alone to see the contents of the JList clearly.For that he clicks "MAXIMIZE PANEL" button.After the click action ,the JPanelD in the JFrame remains there,also a new JPanel with the same JList data(ie.,the replica of the JPanelD say JPanelDMaximized)should be popped up.This is what i want to do ..
Of course you could do this yourself, but you should really look at JInternalFrame and consider using that for your panel. It will save a bunch of headache.
Edit: Sun's tutorial should get you what you need.
Follow-up to your clarification of the problem:
Take my code, and remove:
maximizedFrame.setUndecorated( true );
and size the frame bigger before you make it visible. That should satisfy the maximize-like behaviour you need.
Your other problem is that you cannot add JPanelD to the two JFrames. The pop-up frame must have its own unique JPanel object (let's call it JPanelE). So you need to:
Initialize and lay out JPanelE like you do JPanelD. That means giving JPanelE its own JList (and JTree, and so on).
Share the ListModel from JPanelD's JList with JPanelE's JList, and so on. The feasibility and details of executing this successfully depends on the specifics of your implementation, and is beyond the scope of your original problem.
Create a JWindow (or an undecorated JFrame) with a JPanel. Leave the JWindow invisible, initially. (The wiring of this new JPanel to the same data model used by the original JPanel is left as an exercise.)
When your maximize-panel button's ActionListener executes, it must:
2.1. Update the (invisible) JWindow's location and size to match the (visible) JFrame's.
2.2. Make your JFrame invisible.
2.3. Make your JWindow visible.
When your unmaximize-panel button's ActionListener executes, it must:
3.1. Update the (invisible) JFrame's location and size to match the (visible) JWindow's.
3.2. Make your JWindow invisible.
3.3. Make your JFrame visible
Example:
package stackoverflow;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MaximizingPanelApp extends JFrame {
private JPanel framePanel;
private JPanel windowPanel;
private JFrame maximizedFrame;
public static void main(String[] args) {
JFrame appFrame = new MaximizingPanelApp();
appFrame.setVisible( true );
}
public MaximizingPanelApp() throws HeadlessException {
super( "Application" );
setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
initialize();
}
private void initialize() {
// JFrame
{
Container container = getContentPane();
container.setLayout( new BorderLayout() );
framePanel = new JPanel();
framePanel.setBackground( Color.ORANGE );
container.add( framePanel, BorderLayout.CENTER );
JButton button = new JButton( new MaximizeAction() );
container.add( button, BorderLayout.SOUTH );
setSize( 400, 300 );
}
// JWindow
{
maximizedFrame = new JFrame();
Container container = maximizedFrame.getContentPane();
container.setLayout( new BorderLayout() );
windowPanel = new JPanel();
windowPanel.setBackground( Color.ORANGE );
container.add( windowPanel, BorderLayout.CENTER );
JButton button = new JButton( new UnMaximizeAction() );
container.add( button, BorderLayout.SOUTH );
maximizedFrame.setSize( getSize() );
maximizedFrame.setUndecorated( true );
}
}
private class MaximizeAction extends AbstractAction {
private MaximizeAction() {
super( "Maximize" );
}
public void actionPerformed(ActionEvent e) {
maximizedFrame.setSize( getSize() );
maximizedFrame.setLocation( getLocation() );
setVisible( false );
maximizedFrame.setVisible( true );
}
}
private class UnMaximizeAction extends AbstractAction {
private UnMaximizeAction() {
super( "Un-Maximize" );
}
public void actionPerformed(ActionEvent e) {
setLocation( maximizedFrame.getLocation() );
setSize( maximizedFrame.getSize() );
maximizedFrame.setVisible( false );
maximizedFrame.dispose();
setVisible( true );
}
}
}
This depends on the layout manager you use. If you add a JPanel to a JFrame using the default layout manager, and the JFrame only contains the JPanel and nothing else, you'll achieve what you describe.
Here's an example. The JPanel is green; notice how it resizes as you resize the JFrame.
import javax.swing.*;
import java.awt.*;
public class ScratchSpace {
public static void main(String[] args) {
JFrame frame = new JFrame("Stretchy panel demo");
final JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.GREEN);
panel.setPreferredSize(new Dimension(600, 400));
final JComponent contentPane = (JComponent) frame.getContentPane();
contentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}

Categories

Resources