package helloworld;
import javax.swing.*;
import java.awt.event.*;
public class helloworld extends JFrame{
public static void main( String args[] ){
JFrame frame = new helloworld();
frame.setSize( 400, 200 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "HelloWorld" );
JPanel panel = new Panel();
frame.setContentPane( panel );
frame.setVisible( true );
}
}
class Panel extends JPanel {
private JButton button, resetbutton;
private JTextField textfield;
public Panel(){
button = new JButton( "click" );
button.addActionListener( new ButtonHandler() );
resetbutton = new JButton( "erase" );
resetbutton.addActionListener( new ResetbuttonHandler() );
textfield = new JTextField( 10 );
add( button );
add( textfield );
add( resetbutton );
}
class ButtonHandler implements ActionListener{
public void actionPerformed( ActionEvent e ){
textfield.setText( "you clicked" );
}
}
class ResetbuttonHandler implements ActionListener{
public void actionPreformed( ActionEvent e ){
textfield.setText( "" );
}
}
}
I just set up some basic code to learn a bit more about java. But I have a problem regarding my button classes.
The error says the following: The type Panel.ResetbuttonHandler must implement the inherited abstract method ActionListener.actionPerformed(ActionEvent) Previously I also had this problem with the ButtonHandler class, somehow I solved this problem, but the ResetbuttonHandler still shows the same error, and I couldn't figure out what the differences between them were.I also tried to #Override them, but that didn't work. I've got a book about java (that is also where I'm learning from), and they do this in the exact same way. Even searched the whole internet, still didn't find the solution. I hope that someone can help me with this problem!
Please correct spelling of actionPreformed method to actionPerformed
class ResetbuttonHandler implements ActionListener{
public void actionPerformed( ActionEvent e ){
textfield.setText( "" );
}
}
Related
I have an always-on-top window that I want to remain above all other windows. Using setAlwaysOnTop(true) seems to work for most purposes, but fails when it comes to JComboBox dropdown menus. Is there any way to prevent this from happening? Attached below is a SSCCE and picture of the undesired functionality.
EDIT: Not sure if the behavior is OS-dependent, but I'm noticing the issue on Windows 7 using Java 7. On top is supported on this OS.
EDIT 2: Seems that JPopupMenu has an override on alwaysOnTop() to return true. This is the source of the problem, since on-top components do not have a defined order in how they appear on top of each other (OS-dependent). Worse still, the method is package private. Quite problematic...
Undesired Behavior:
SSCCE:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JTextField;
public class OnTopTest
{
public static void main( String[] args )
{
new OnTopTest();
}
public OnTopTest()
{
JDialog onTop = new OnTopWindow();
JDialog other = new OtherWindow();
System.out.println("IS ON TOP SUPPORTED? " + onTop.isAlwaysOnTopSupported());
other.setVisible( true );
onTop.setVisible( true );
}
private class OnTopWindow extends JDialog
{
public OnTopWindow()
{
setLayout( new BorderLayout() );
JButton button = new JButton("Button");
add( button, BorderLayout.CENTER );
setSize( 100, 100 );
setAlwaysOnTop( true );
}
}
private class OtherWindow extends JDialog
{
public OtherWindow()
{
setLayout( new BorderLayout() );
JTextField textField = new JTextField("Text");
add( textField, BorderLayout.NORTH);
JButton button = new JButton("Button");
add( button, BorderLayout.CENTER );
JComboBox comboBox = new JComboBox( new Object[] {"Item1", "Item2", "Item3"} );
add( comboBox, BorderLayout.SOUTH );
setSize( 200, 200 );
}
}
}
I'm pretty sure this is handled by the Operating System and that Java cannot force the dropdown to not overlap the other window, as searching for this without specifying Java reported the same behaviour in many different languages.
You can test with a JMenu to confirm, but I'm sure it will also happen as menus and some other controls (like dropdowns) will (by necessity) show above any other window.
Error: Strange enough I get no errors.
What I'm trying to make: ( I also added // messages that explains what my code does.)
What I'm trying to make is fairly simple.
1) Fill in a name in the JTextField, press enter and the name should appear in the JTextArea. After the name is in the JTextArea the JTextField becomes empty so you can fill another name and so on there should appear a list of names in JTextArea.
2) Push the button kiesWin to make the program choose a random person from the list. (here it goes wrong)
3) Push the button resetL to reset the program so I can make a new list to choose a random winner from it.
Problem: When I Push the button Kies (Translated: Choose) it should choose a random name from the ArrayList and show the random name in the JTextField textvak2. But when I push the button Kies the program does nothing. And it should show me the random chosen name from the ArrayList.
This is the class that doesn't works properly: (I Think)
// This is the button that chooses a random name from the ArrayList.
// The random chosen name should appear in the JTextField textvak2. (but it doesn't)
// This is also the part where it goes wrong at the moment.
class Kies extends OnthoudNaam implements ActionListener {
public void actionPerformed( ActionEvent e ) {
Random r = new Random();
if (lijst.size() > 0) {
int n = r.nextInt(lijst.size());
Naam kiesNaam = lijst.get(n);
textvak2.setText(kiesNaam.getIngevoerdNaam());
}
}
}
For in case you need the whole code:
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
// Main method to make the frame.
public class Loterij3 extends JFrame {
public static void main( String args[] ) {
JFrame frame = new Loterij3();
frame.setExtendedState( frame.MAXIMIZED_BOTH );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setTitle( "My Lottery!" );
frame.setContentPane( new Paneel() );
frame.setVisible( true );
}
}
// This is the Panel that goes into the frame.
class Paneel extends JPanel {
private Boven boven;
JTextArea textvak1;
JTextField textvak2;
OnthoudNaam onthoudNaam = new OnthoudNaam();
JTextField invoervak1; // JTextField from class Boven.
public Paneel() {
setLayout( new BorderLayout() ); // using border Layout.
setBackground( Color.LIGHT_GRAY );
boven = new Boven();
textvak1 = new JTextArea();
add( new JScrollPane( textvak1 ) );
textvak1.setBackground( Color.WHITE );
textvak2 = new JTextField();
textvak2.setHorizontalAlignment(JTextField.CENTER);
add( boven, BorderLayout.NORTH ); // Where the class Boven should be.
add( textvak1, BorderLayout.CENTER );
add( textvak2, BorderLayout.SOUTH );
}
// This is the class Boven (Translation up or upper).
// This is where the JButtons, JTextField and JLabels are.
public class Boven extends JPanel {
JButton kiesWin, resetL;
JLabel label1;
public Boven() {
setBackground( Color.LIGHT_GRAY );
setLayout( new GridLayout( 1, 4, 100, 5 ) ); // using GridLayout.
Border border =
BorderFactory.createEmptyBorder( 10, 10, 10, 10 );
setBorder( border );
kiesWin = new JButton("Kies een Winnaar!");
kiesWin.addActionListener( new Kies() );
resetL = new JButton("Reset alles");
resetL.addActionListener( new Reset() );
label1 = new JLabel("Voer Persoon in en druk op enter: ", JLabel.RIGHT);
invoervak1 = new JTextField( 20 );
invoervak1.addActionListener( new InvoerVakHandler() );
add( label1 );
add( invoervak1 );
add( kiesWin );
add( resetL );
}
}
// The class Naam (translation = name).
// This is what the ArrayList should remember
// In other words ArrayList should remember the Names I put in the JTextField.
class Naam {
private String ingevoerdNaam;
public Naam( String ingevoerdNaam) {
this.ingevoerdNaam = ingevoerdNaam;
}
public String getIngevoerdNaam() {
return ingevoerdNaam;
}
public String toString() {
return ingevoerdNaam;
}
}
// This is my ArrayList,
// This should remember the names I type in the JTextField.
class OnthoudNaam extends JPanel {
protected ArrayList<Naam> lijst;
public OnthoudNaam() {
lijst = new ArrayList<Naam>();
}
public void voegNaamToe(Naam x ) {
lijst.add(x);
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for(Naam x : lijst ) {
buffer.append( x );
buffer.append( "\n" );
}
return buffer.toString();
}
}
// This is the JTextField where I enter the names.
// The Name I fill in the JTextField should be remembered by the ArrayList.
// The Name I fill in should be put in the JTextArea.
public class InvoerVakHandler implements ActionListener {
public void actionPerformed( ActionEvent e ) {
String invoer = invoervak1.getText();
Naam Naam = new Naam( invoer );
onthoudNaam.voegNaamToe( Naam );
textvak1.setText( onthoudNaam.toString() );
invoervak1.setText( "" );
}
}
// This is the button that chooses a random name from the ArrayList.
// This is also the part where it goes wrong at the moment.
class Kies extends OnthoudNaam implements ActionListener {
public void actionPerformed( ActionEvent e ) {
Random r = new Random();
if (lijst.size() > 0) {
int n = r.nextInt(lijst.size());
Naam kiesNaam = lijst.get(n);
textvak2.setText(kiesNaam.getIngevoerdNaam());
}
}
}
// This should become the button that resets everything so you can start over.
class Reset implements ActionListener {
public void actionPerformed( ActionEvent e ) {
}
}
}
Random#nextInt requires a positive number but the initial size of the List lijst is 0 hence the Exception
The docs clearly state this
Throws:
IllegalArgumentException - if n is not positive
Check that there are entries in the List first.
if (lijst.size() > 0) {
int n = r.nextInt(lijst.size());
Naam kiesNaam = lijst.get(n);
textvak2.setText(kiesNaam.getIngevoerdNaam());
}
Aside: Rather than casting the object from the List, extract the Naam object and use its getIngevoerdNaam method.
Remember too The debugger is your friend
In NetBeans, I have used the GUI editor to make a JFrame and I've put a JPanel in the frame.
At the moment, I'm trying to make a new button in the panel when the class constructs.
This is the code I have, but I can't seem to get it to work.
(The first line makes the button, the other lines try to show it.)
this.jPanel2.add(new JButton("Test"),BorderLayout.NORTH);
this.jPanel2.validate();
this.jPanel2.revalidate();
this.jPanel2.repaint();
this.jPanel2.setVisible(true);
this.revalidate();
this.setVisible(true);
this.repaint();
I've been googling all night, but can't seem to get it to work.
Some times when you don't see a button it is a layout manager issue (as in you aren't setting the right properties for the layout manager). You can test this by disabling it:
this.jPanel2.setLayoutManager(null);
And setting bounds for the button (JButton.setBounds()).
If the above fixes your problem, then you need to look into the requirements set by the LayoutManager you are using (see also the answer by Robin).
All the calls to validate(), revalidate() and repaint() are not needed to do this.
Normally the add call is sufficient.
Note: a BorderLayout can only contain one component in each location. So if you add another component in the NORTH location, your button will not be visible.
Second note: by default a JPanel does not have a BorderLayout but a FlowLayout. Have you set a BorderLayout on that specific panel ? Otherwise the BorderLayout#NORTH constraint is incorrect
All the validate,revalidate,repaint calls can be removed
Edit
It seems some sort of validation is needed after all. I was under the impression that Swing should be smart enough to listen for the event when something is added to a Container, and update whatever is necessary (a bit similar to updating a TableModel updates the JTable based on events, without the need to call repaint or the likes on the JTable).
However, when trying this in an SSCCE, I came to the following code (different versions, only post the most elaborate version)
without the scroll-pane, the validate calls seem to have no effect. I actually need to call pack again to make the new labels visible (not included in the SSCCE, but removing the scrollpane from the code is trivial)
with the scroll-pane, the validate call has an effect
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class AddLabelsAtRuntime {
private int fLabelCounter = 0;
private JPanel fLabelPanel;
private final JFrame fTestFrame;
public AddLabelsAtRuntime() {
fLabelPanel = new JPanel( );
BoxLayout boxLayout = new BoxLayout( fLabelPanel, BoxLayout.PAGE_AXIS );
fLabelPanel.setLayout( boxLayout );
fTestFrame = new JFrame( "Dynamically add labels" );
}
private JFrame createUI(){
Container contentPane = fTestFrame.getContentPane();
contentPane.setLayout( new BorderLayout() );
JScrollPane scrollPane = new JScrollPane( fLabelPanel );
scrollPane.setPreferredSize( new Dimension( 200, 200 ) );
contentPane.add( scrollPane, BorderLayout.CENTER );
contentPane.add( createButtonPanel(), BorderLayout.SOUTH );
fTestFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
fTestFrame.pack();
return fTestFrame;
}
private void addLabel(){
fLabelPanel.add( new JLabel( "Label " + ++fLabelCounter ) );
}
private JPanel createButtonPanel(){
JPanel buttonPanel = new JPanel( );
BoxLayout boxLayout = new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS );
buttonPanel.setLayout( boxLayout );
JButton validateButton = new JButton( "Add + validate" );
validateButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
fLabelPanel.validate();
fTestFrame.validate();
}
} );
buttonPanel.add( validateButton );
JButton noValidateButton = new JButton( "Add" );
noValidateButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
}
} );
buttonPanel.add( noValidateButton );
JButton packButton = new JButton( "Add + pack" );
packButton.addActionListener( new ActionListener() {
#Override
public void actionPerformed( ActionEvent e ) {
addLabel();
fTestFrame.pack();
}
} );
buttonPanel.add( packButton );
return buttonPanel;
}
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
AddLabelsAtRuntime addLabelsAtRuntime = new AddLabelsAtRuntime();
addLabelsAtRuntime.createUI().setVisible( true );
}
} );
}
}
Create Dynamic JButton with Image and ActionListener - Java Swing
Create JButton dynamically with Image and the ActionListener . You will be able to change the button height , width horizontal gap and vertical gap in one place.
you can find more details from here
I write a program in java and used a several components that takes action(actionListener) in my program.
I want to know when any action happened by this component. For example when I clicked the button or a menu item , call a method.
public class ButtonFrame extends JFrame
{
private JButton plainJButton; // button with just text
private JButton fancyJButton; // button with icons
public ButtonFrame()
{
super( "Testing Buttons" );
setLayout( new FlowLayout() ); // set frame layout
plainJButton = new JButton( "Plain Button" );
add( plainJButton );
fancyJButton = new JButton( "Fancy Button");
add( fancyJButton );
// create new ButtonHandler for button event handling
ButtonHandler handler = new ButtonHandler();
fancyJButton.addActionListener( handler );
plainJButton.addActionListener( handler );
}
private class ButtonHandler implements ActionListener
{
public void actionPerformed( ActionEvent event )
{
JOptionPane.showMessageDialog( ButtonFrame.this, String.format(
"You pressed: %s", event.getActionCommand() ) );
}
}
}
Use event.getSource() to differentiate between registered components.
Example -
if(plainJButton == event.getSource()){
// do stuff (e.g. show message dialog, invoke method, and etc.)
}
else if(fancyJButton == event.getSource()){
// do stuff (e.g. show message dialog, invoke method, and etc.)
}
else{
// ut-oh..time to panic!
}
You can use getSource() on the event.
I have a java program with a JFrame and 3 JButtons in it. I have added a keylistener to jframe. When i run the program a jframe window is opened and the first button is selected by default. My problem is that a KeyEvent is not being generated by this JFrame.
Now, besides adding a KeyListener to the jframe, i also added a KeyListener to the buttons.
Now the keyevent is being generated by the buttons.
How do I make the JFrame generate KeyEvent instead of the JButton generating them ??
Actually, my main purpose is building keyboard shortcuts for the buttons.
Have a look here How to Use Key Bindings.
An alternative to keylistener.
Here is a little Example it has a Button with focus and process a KeyEvent (F2).
On F2-clicked the Key-Binding process a ButtonClick which performed a System.out print.
public class Example {
static public void main( String[] s ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.getContentPane().setLayout( new BorderLayout() );
frame.setBounds( 50, 50, 600, 600 );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
final JButton button = new JButton( new AbstractAction("MyButton") {
#Override
public void actionPerformed( ActionEvent e ) {
System.out.println("Button Clicked");
}
});
frame.getContentPane().add( button );
frame.getRootPane().setDefaultButton( button );
KeyStroke f2 = KeyStroke.getKeyStroke("F2");
frame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(f2, "clickButton");
frame.getRootPane().getActionMap().put("clickButton", new AbstractAction() {
#Override
public void actionPerformed( ActionEvent e ) {
button.doClick();
}
});
frame.setVisible( true );
// the Button has the focus
button.requestFocus();
// generate a KeyEvent 'F2'
KeyboardFocusManager.getCurrentKeyboardFocusManager().dispatchKeyEvent( new KeyEvent( frame, KeyEvent.KEY_PRESSED, 0, f2.getModifiers(), f2.getKeyCode(), f2.getKeyChar() ) );
}
});
}
}
The key event is called on the currently focused component (which is usually not the JFrame)