Paint Swing JButton as disabled - java

I want to display a normal JButton as disabled, without setting it to setEnabled(false)!
I just want to show that this button is not enabled, but if the user pushs the button it should call the actionlistener as normal.
So what I did is:
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SwingTests {
private static void createWindow() {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
MyButton button = new MyButton("Press");
button.setEnabled(false);
panel.add(button);
frame.add(panel);
frame.setSize(200, 200);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createWindow();
}
});
}
}
class MyButton extends JButton {
private boolean enabled = false;
public MyButton(String text) {
super(text);
super.setEnabled(true);
}
#Override
protected void paintBorder(Graphics g) {
if (isEnabled())
super.paintBorder(g);
else
; // paint disabled button
}
#Override
protected void paintComponent(Graphics g) {
if (isEnabled())
super.paintComponent(g);
else
; // paint disabled button
}
#Override
public void setEnabled(boolean b) {
enabled = b;
}
#Override
public boolean isEnabled() {
return enabled;
}
}
I "just" need to know what to write in paintComponent(g) and paintBorder(g).

if it is disabled and a user pushs the button i display an alarm why this button is disabled!
If it looks disabled I am probably not going to push it in the first place. You could achieve this type of effect using tool tips.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
public class TestGUI {
public TestGUI() {
JFrame frame = new JFrame();
final JButton button = new JButton("Press Me");
final JToggleButton enable = new JToggleButton("Enable / Disable");
enable.setSelected(true);
button.setToolTipText("Enabled");
enable.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (enable.isSelected()) {
button.setEnabled(true);
button.setToolTipText("Enabled");
} else {
button.setEnabled(false);
button.setToolTipText("Not Enabled");
}
}
});
frame.add(button, BorderLayout.CENTER);
frame.add(enable, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestGUI();
}
});
}
}

if it is disabled and a user pushs the button i display an alarm why this button is disabled!
Add a MouseListener to the button when it is disabled. Then you can handle the mouseClicked() event to display your "alarm".

Related

JFrame moves to the background for some reason

After I asked a very vague question about this topic yesterday here (which I voted to close now), I was able to pinpoint the problem and create a MCVE which shows this behavior.
The scenario looks like this:
While some operation is ongoing in the background, a Modal "Wait" Dialog is provided in the foreground, also the JFrame is being set to be disabled, just to be sure. After the background task is finished, the Frame is enabled again and the dialog disposed.
The issue is, that after the JFrame is being enabled and a modal dialog is disposed, the JFrame suddenly moves to the background. With "background" meaning, it is moving behind the window that had focus before the JFrame. Why does this happen?
This code should replicate the issue:
private static JFrame frame;
private static JDialog dialog;
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
buildFrame();
buildDialog();
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
protected static void buildDialog() {
dialog = new JDialog(frame);
dialog.getContentPane().add(new JLabel("This is the dialog"));
dialog.setLocationRelativeTo(frame);
javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
frame.setEnabled(true);
}
});
t.setRepeats(false);
t.start();
dialog.pack();
dialog.setVisible(true);
}
protected static void buildFrame() {
frame = new JFrame();
frame.setMinimumSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JLabel("This is the Frame"));
frame.setEnabled(false);
frame.pack();
frame.setVisible(true);
}
Does anyone know why this happens and how this could be prevented?
The problem is the methods frame.setEnabled(). I don't know why, but it hides the frame. My suggestion is to remove it and use the modality concept: dialog.setModal(true) (it also makes the parent frame unavailable when the dialog is shown. To make the frame unavailable, you can place a glasspane over it. Here is the code:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseAdapter;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/**
* <code>DialogFrameTest</code>.
*/
public class DialogFrameTest {
private static JFrame frame;
private static JDialog dialog;
private static Component oldGlassPane;
public static void main(String[] args) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
buildFrame();
buildDialog();
}
});
} catch (InvocationTargetException | InterruptedException e) {
e.printStackTrace();
}
}
protected static void buildDialog() {
dialog = new JDialog(frame);
dialog.getContentPane().add(new JTextField("This is the dialog"));
dialog.setLocationRelativeTo(frame);
dialog.setModal(true);
javax.swing.Timer t = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
dialog.dispose();
frame.setGlassPane(oldGlassPane);
oldGlassPane.setVisible(false);
}
});
t.setRepeats(false);
t.start();
dialog.pack();
dialog.setVisible(true);
}
protected static void buildFrame() {
frame = new JFrame();
frame.setMinimumSize(new Dimension(400, 400));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JTextField("This is the Frame"));
oldGlassPane = frame.getGlassPane();
frame.setGlassPane(new SplashGlassPane());
frame.getGlassPane().setVisible(true);
frame.pack();
frame.setVisible(true);
}
private static class SplashGlassPane extends JPanel implements FocusListener {
/** Holds the id of this panel. The creator of this object can submit this id to determine whether it's the owner of this object. */
private String typeId;
/**
* Creates new GlassPane.
*/
public SplashGlassPane() {
addMouseListener(new MouseAdapter() {});
addMouseMotionListener(new MouseAdapter() {});
addFocusListener(this);
setOpaque(false);
setFocusable(true);
setBackground(new Color(0, 0, 0, 100));
}
#Override
public final void setVisible(boolean v) {
// Make sure we grab the focus so that key events don't go astray.
if (v) {
requestFocus();
}
super.setVisible(v);
}
// Once we have focus, keep it if we're visible
#Override
public final void focusLost(FocusEvent fe) {
if (isVisible()) {
requestFocus();
}
}
/**
* {#inheritDoc}
*/
#Override
public final void paint(Graphics g) {
final Color old = g.getColor();
g.setColor(getBackground());
g.fillRect(0, 0, getSize().width, getSize().height);
g.setColor(old);
super.paint(g);
}
#Override
public void focusGained(FocusEvent fe) {
// nothing to do
}
}
}

Prevent JButton repaint() after click

I have a button. I want to change the background after I click on it. My problem here is the button auto call paintComponent(). How can prevent this? I expect after clicking the button the button will be blue, but it will still be red.
package test;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonDemo extends JButton implements ActionListener{
public ButtonDemo() {
this.setText("BUTTON TEXT");
this.addActionListener(this);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.RED);
}
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo());
frame.setSize(500, 500);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
this.setBackground(Color.BLUE);
}
}
My personal gut feeling is that JButton is probably not suited to your desired goal.
Essentially, you want to control when and how the "selected" state of the piece is changed.
Personally, I would have some kind of controller which monitored the mouse events in some way (probably having the piece component delegate the event back to the controller) and some kind of model which control when pieces become selected, this would then notify the controller of the state change and it would make appropriate updates to the UI.
But that's a long process to setup. Instead, I'm demonstrating a simple concept where a component can be selected with the mouse, but only the controller can de-select. In this example, this will allow only a single piece to be selected
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridLayout(5, 5));
ChangeListener listener = new ChangeListener() {
private PiecePane selectedPiece;
#Override
public void stateChanged(ChangeEvent e) {
if (!(e.getSource() instanceof PiecePane)) { return; }
PiecePane piece = (PiecePane) e.getSource();
// Want to ignore events from the selected piece, as this
// might interfer with the changing of the pieces
if (selectedPiece == piece) { return; }
if (selectedPiece != null) {
selectedPiece.setSelecetd(false);
selectedPiece = null;
}
selectedPiece = piece;
}
};
for (int index = 0; index < 5 * 5; index++) {
PiecePane pane = new PiecePane();
pane.addChangeListener(listener);
add(pane);
}
}
}
public class PiecePane extends JPanel {
private boolean selecetd;
private Color selectedBackground;
private Color normalBackground;
private MouseListener mouseListener;
public PiecePane() {
setBorder(new LineBorder(Color.DARK_GRAY));
mouseListener = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
setSelecetd(true);
}
};
setNormalBackground(Color.BLUE);
setSelectedBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
#Override
public void addNotify() {
super.addNotify();
addMouseListener(mouseListener);
}
#Override
public void removeNotify() {
super.removeNotify();
removeMouseListener(mouseListener);
}
public void addChangeListener(ChangeListener listener) {
listenerList.add(ChangeListener.class, listener);
}
public void removeChangeListener(ChangeListener listener) {
listenerList.remove(ChangeListener.class, listener);
}
protected void fireSelectionChanged() {
ChangeListener[] listeners = listenerList.getListeners(ChangeListener.class);
if (listeners.length == 0) {
return;
}
ChangeEvent evt = new ChangeEvent(this);
for (int index = listeners.length - 1; index >= 0; index--) {
listeners[index].stateChanged(evt);
}
}
public boolean isSelected() {
return selecetd;
}
public void setSelecetd(boolean selecetd) {
if (selecetd == this.selecetd) { return; }
this.selecetd = selecetd;
updateSelectedState();
fireSelectionChanged();
}
public Color getSelectedBackground() {
return selectedBackground;
}
public void setSelectedBackground(Color selectedBackground) {
this.selectedBackground = selectedBackground;
updateSelectedState();
}
public Color getNormalBackground() {
return normalBackground;
}
public void setNormalBackground(Color normalBackground) {
this.normalBackground = normalBackground;
updateSelectedState();
}
protected void updateSelectedState() {
if (isSelected()) {
setBackground(getSelectedBackground());
} else {
setBackground(getNormalBackground());
}
}
}
}
I created a toggle button.
You set the primary color and the alternate color in the class constructor.
When you call the switchColors method, the JButton background changes from the primary color to the alternate color. When you call the switchColors method again, the JButton background changes from the alternate color to the primary color.
In the following example, I put the switchColors method in the actionListener so you can see the color change. Each time you left-click on the JButton, the background color changes.
You would call the switchColors method when you want the JButton background to change from blue to red, and again when you want the JButton background to change from red to blue. It's under your control.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ButtonDemo extends JButton
implements ActionListener {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Button Demo");
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo(Color.BLUE,
Color.RED));
frame.setSize(300, 300);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
private boolean primaryBackground;
private Color primaryColor;
private Color alternateColor;
public ButtonDemo(Color primaryColor,
Color alternateColor) {
this.primaryColor = primaryColor;
this.alternateColor = alternateColor;
this.primaryBackground = true;
this.setText("BUTTON TEXT");
this.setBackground(primaryColor);
this.addActionListener(this);
}
public void switchColors() {
primaryBackground = !primaryBackground;
Color color = primaryBackground ? primaryColor :
alternateColor;
this.setBackground(color);
}
#Override
public void actionPerformed(ActionEvent e) {
switchColors();
}
}
If you want to change the background for a short while you can do it with swing Timer:
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ButtonDemo extends JButton implements ActionListener{
private static final int DELAY = 600; //milliseconds
private final Timer timer;
public ButtonDemo() {
this.setText("BUTTON TEXT");
this.addActionListener(this);
Color defaultCloor = getBackground();
timer = new Timer(DELAY, e-> setBackground(defaultCloor));
timer.setRepeats(false);
}
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel contentPane = new JPanel();
frame.setContentPane(contentPane);
contentPane.add(new ButtonDemo());
frame.setSize(300, 200);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
this.setBackground(Color.RED);
timer.start();
}
}

How to make an Auto Clicker with Java?

So I wanted to make a program that holds down the mouse button for me.
So far I've got this: http://pastebin.com/UTJwdHY7
What I'm wondering is how I can stop it. Also, what I realise is that stopping the button makes no sense as I wouldn't be able to click it anyway. Also some tips on how I've done so far would be nice.
Edit (Adding code):
package main;
import javax.swing.*;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.beans.PropertyChangeListener;
public class clickForever extends JFrame implements ActionListener {
public static boolean isClicking = false;
public void actionPerformed(ActionEvent e) {}
public void createFrame() { initComponents(); }
public void initComponents() {
JFrame frame = new JFrame("AutoClicker");
JPanel panel = new JPanel(true);
JButton button = new JButton("OKAY");
JLabel label = new JLabel();
frame.setVisible(true);
frame.setSize(350, 67);
frame.setResizable(false);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.add(panel);
button.addActionListener(new Action() {
#Override
public Object getValue(String s) {
return null;
}
#Override
public void putValue(String s, Object o) {}
#Override
public void setEnabled(boolean b) {}
#Override
public boolean isEnabled() {
return false;
}
#Override
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {}
#Override
public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) {}
#Override
public void actionPerformed(ActionEvent actionEvent) {
if(isClicking){isClicking = false; return;}
if(!isClicking){isClicking = true; return;}
}
});
label.setFont(new Font("Times New Roman", 1, 16));
label.setText("Click 'OKAY' to start.");
label.setBorder(BorderFactory.createLineBorder(Color.black));
panel.add(label);
panel.setBorder(new LineBorder(Color.BLACK));
panel.add(button);
}
public static void main(String[] args) throws java.awt.AWTException, java.lang.InterruptedException {
clickForever clickForever = new clickForever();
Robot rbt = new Robot();
clickForever.createFrame();
while(true){
if(isClicking) rbt.mousePress(InputEvent.BUTTON1_MASK);
if(!isClicking) ;
}
}
}
Add a key listener to the frame, and when the key is pressed, stop the pressing. Note that this will not work if the frame goes out of focus, in which case you would have to listen for a global key press, which I believe would be much more difficult.
You Can Use This To End Your Program And Try Link It To The Press Of A button
Code:
public class Main {
public static void main(String[] args) {
System.out.println("Statement 1");
System.exit(0);
System.out.println("Statement 2");
}
}

Using Images as Buttons, getting a Blank Screen

I'm trying to add an Image button to my GUI but all I get is a blank screen. Can anyone show me whats wrong with my code? This is what I have so far.
package fallingStars;
import java.awt.*;
import java.awt.event.*;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class GUI extends JFrame
{
private JLabel label;
private JButton button;
private JPanel buttonPanel;
public static void startButton()
{
ImageIcon start = new ImageIcon("Start.png");
JButton play = new JButton(start);
play.setBounds(150,100,100,50);
}
public static void main(String args[])
{
GUI gui = new GUI();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setSize(300, 500);
gui.setVisible(true);
gui.setResizable(false);
gui.setTitle("Falling Stars");
JPanel panel = new JPanel();
startButton();
}
}
You have to add the JButton to the container using container.add(JButton);
You're going to get a blank screen if you don't actually add it :)
First of all just insert an ImageIcon in JLabel. If you want an image act as button, you have to add MouseListener & implement mouseClicked() as I did.
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class MyFrame extends JFrame{
private JLabel label;
private static MyFrame frame;
public MyFrame(){
initComponent();
label.addMouseListener(new MouseListener(){
#Override
public void mouseClicked(MouseEvent arg0) {
JOptionPane.showMessageDialog(frame, "You just clicked the image");
}
#Override
public void mouseEntered(MouseEvent arg0) {}
#Override
public void mouseExited(MouseEvent arg0) {}
#Override
public void mousePressed(MouseEvent arg0) {}
#Override
public void mouseReleased(MouseEvent arg0) {}
});
}
private void initComponent() {
this.setSize(400, 400);
this.setLocationRelativeTo(null);
label = new JLabel();
label.setIcon(new ImageIcon(getClass().getResource("res/image.png")));
add(label);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible (true);
}
public static void main(String[] args) {
frame = new MyFrame();
}
}

how to modify current JPanel and JFrame in java

I am using the following code:
class ButtonPanel extends JPanel implements ActionListener
{
public ButtonPanel()
{
yellowButton=new JButton("Yellow");
blueButton=new JButton("Blue");
redButton=new JButton("Red");
add(yellowButton);
add(blueButton);
add(redButton);
yellowButton.addActionListener(this);
blueButton.addActionListener(this);
redButton.addActionListener(this);
}
public void actionPerformed(ActionEvent evt)
{
Object source=evt.getSource();
Color color=getBackground();
if(source==yellowButton) color=Color.yellow;
else if (source==blueButton) color=Color.blue;
else if(source==redButton) color=Color.red;
setBackground(color);
repaint();
}
private JButton yellowButton;
private JButton blueButton;
private JButton redButton;
}
class ButtonFrame extends JFrame
{
public ButtonFrame()
{
setTitle("ButtonTest");
setSize(400,400);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
Container contentPane=getContentPane();
contentPane.add(new ButtonPanel());
}
}
public class ButtonTest
{
public static void main(String args[])
{
JFrame frame=new ButtonFrame();
frame.show();
}
}
In actionperformed() I want to modify my panel and add some more component, is there any way to do this?
Yes.
Just call add() for the panel and then revalidate() and repaint();
but in actionperformed() i want to modify my panel and want to add some more component... Is there any way to do this....
Yes, you can add the components to the JPanel or "this" via the add(...) method, and you'll need to call revalidate() and then sometimes repaint() (especially if you also remove components) on the JPanel (this). But before you do this, if you haven't already done so, I think that you'll want to read the tutorials on using the layout managers so you can add components that are well situated.
hmmm I hard to comment anything, there are lots of mistakes, please start with this code
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ButtonPanel extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private JButton yellowButton;
private JButton blueButton;
private JButton redButton;
public ButtonPanel() {
yellowButton = new JButton("Yellow");
yellowButton.addActionListener(this);
blueButton = new JButton("Blue");
blueButton.addActionListener(this);
redButton = new JButton("Red");
redButton.addActionListener(this);
add(yellowButton);
add(blueButton);
add(redButton);
setPreferredSize(new Dimension(400, 400));
}
#Override
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
Color color = getBackground();
if (source == yellowButton) {
color = Color.yellow;
} else if (source == blueButton) {
color = Color.blue;
} else if (source == redButton) {
color = Color.red;
}
setBackground(color);
revalidate();
repaint();
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("ButtonTest");
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.add(new ButtonPanel());
frame.pack();
frame.setVisible(true);
}
});
}
}

Categories

Resources