good day!
I'm making an attendance-checking program that displays an orange button when clicked once, red button, for two clicks and black button for 3. I'm having problem as to how to accumulate getClickCount() values, because for the buttons to register 3 clicks, the buttons have to be clicked at 3 times quickly.
Here's the code
button1.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent a){
if (a.getClickCount() == 1){
button1.setBackground(Color.ORANGE);
}
else if (a.getClickCount() == 2){
button1.setBackground(Color.RED);
}
else if (a.getClickCount() == 3){
button1.setBackground(Color.BLACK);
}
}
});
frame.setVisible(true);
frame.pack();
}
}
If I understand correctly, basically you want to change the color each time the button is pressed, based on the number of times the button has previously been pressed.
MouseListener is not a good choice for JButton, as buttons can be activated by the keyboard (via short cuts or focus activity) and programically, none of which the MouseListener will detect.
Instead, you should use a ActionListener
This example will change the color each time the button is clicked. I've used an array of Colors to make life simpler, but the general concept should work for if-else statements, you just need to reset the counter when it reaches its limit
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ButtonClicker {
public static void main(String[] args) {
new ButtonClicker();
}
public ButtonClicker() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
private static final Color[] COLORS = new Color[]{Color.ORANGE, Color.RED, Color.BLACK};
private int clickCount;
public TestPane() {
setLayout(new GridBagLayout());
JButton clicker = new JButton("Color Changer");
clicker.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
clickCount++;
setBackground(COLORS[Math.abs(clickCount % COLORS.length)]);
}
});
setBackground(COLORS[clickCount]);
add(clicker);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
Take a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners for more details
Step 1: Create your own MouseListener class. In this case, I chose to create an external class that extends MouseAdapter.
public class MyMouseListener extends MouseAdapter
{
public void mousePressed(MouseEvent event)
{
Object obj = event.getSource();
if (obj instanceof JButton)
{
if JButton btn = (JButton)obj;
if (a.getClickCount() == 1)
{
btn.setBackground(Color.ORANGE);
}
else if (a.getClickCount() == 2)
{
btn.setBackground(Color.RED);
}
else if (a.getClickCount() == 3)
{
btn.setBackground(Color.BLACK);
}
}
}
}
Step 2: Add independent instances of this listener to each button
button1.addMouseListener(new MyMouseListener());
button2.addMouseListener(new MyMouseListener());
button3.addMouseListener(new MyMouseListener());
button4.addMouseListener(new MyMouseListener());
button5.addMouseListener(new MyMouseListener());
button6.addMouseListener(new MyMouseListener());
button7.addMouseListener(new MyMouseListener());
button8.addMouseListener(new MyMouseListener());
button9.addMouseListener(new MyMouseListener());
button10.addMouseListener(new MyMouseListener());
button11.addMouseListener(new MyMouseListener());
button12.addMouseListener(new MyMouseListener());
That should work for you. However, as I mentioned, this works OK, but not great.
Related
My program seems to run fine, except for the delete part. Every time I click on the 'delete' button, it deletes itself. So my question is, how would I delete a selected button after I clicked on the "delete" button?
Here is a snippet of my code:
public class DeleteButton extends JFrame implements ActionListener
{
JButton b18a = new JButton("Delete");
JPanel panel = new JPanel();
panel.add(b18);
class ClickListenerTwo implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton buttonThatWasClicked = (JButton) e.getSource();
Container parent = buttonThatWasClicked.getParent();
parent.remove(buttonThatWasClicked);
parent.revalidate();
parent.repaint();
}
}
}
ActionListener b18aClicked = new ClickListenerTwo();
b18a.addActionListener(b18aClicked);
P.S - This selected button that I'm talking about is made during run time, so I want to delete it during run time too, if that would be possible. Thanks!
So, assuming that you need to click the "other" button first, you could use an instance field to maintain a reference to the "last" clicked button and then use that when the delete button is clicked
For example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
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.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton lastButton;
public TestPane() {
JPanel grid = new JPanel(new GridLayout(8, 8));
for (int index = 0; index < 8 * 8; index++) {
JButton btn = new JButton(Integer.toString(index + 1));
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
lastButton = btn;
}
});
grid.add(btn);
}
JButton delete = new JButton("Delete");
delete.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (lastButton != null) {
lastButton.getParent().remove(lastButton);
grid.revalidate();
grid.repaint();
}
lastButton = null;
}
});
setLayout(new BorderLayout());
add(grid);
add(delete, BorderLayout.SOUTH);
}
}
}
Personally, a JToggleButton would give a better user experience
You have to find the Component from the Top Frame.
May be this code will help you.
public void actionPerformed(ActionEvent evt) {
Object source = evt.getSource();
if (source instanceof Component) {
Window w = findWindow((Component) source);
//Find your component and remove it from this window.
} else {
System.out.println("source is not a Component");
}
}
public static Window findWindow(Component c) {
System.out.println(c.getClass().getName());
if (c instanceof Window) {
return (Window) c;
} else if (c instanceof JPopupMenu) {
JPopupMenu pop = (JPopupMenu) c;
return findWindow(pop.getInvoker());
} else {
Container parent = c.getParent();
return parent == null ? null : findWindow(parent);
}
}
To abstract this problem, I put 2 buttons. One is called "Add & toTop", another is called "toTop"
And there is no text in the textArea at the very beginning.
And I add the actionListener for "Add & toTop" button like this:
btn1.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
textArea1.setText("jhggjhg\nhugffsrdtfg\ngfdrtdf\nhgftrsdf\nytfresrdcfvg\nuytyrdtesrdfgg\ntdrfygvhct\njh"
+ "gfda\njftyuyiugcf\nhfuygihvftyughbuy\nhgyuftydfhgfyc\ndstryrfdts");
//A long enough String
JScrollBar jb = scrollPane1.getVerticalScrollBar();
jb.setValue(jb.getMinimum());
scrollPane1.repaint();
}
});
So the function of the first button is :"Add some text and Scroll to Top"
But it will only add text but will not scroll to top
However for the second button, I add a actionListener like this:
btn2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JScrollBar VerticalScrollBar = scrollPane1.getVerticalScrollBar();
VerticalScrollBar.setValue(VerticalScrollBar.getMinimum());
scrollPane1.repaint();
}
});
So, I press the second button after pressing the first button, the second button will perform well.
And I really feel confused that why the first button will not scroll to top :<
A simple solution might be to use JTextArea#setCaretPosition, for example
import java.awt.BorderLayout;
import java.awt.EventQueue;
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTextArea ta;
public TestPane() {
setLayout(new BorderLayout());
ta = new JTextArea(5, 20);
add(new JScrollPane(ta));
JButton btn = new JButton("Add and to top");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
ta.setText("jhggjhg\nhugffsrdtfg\ngfdrtdf\nhgftrsdf\nytfresrdcfvg\nuytyrdtesrdfgg\ntdrfygvhct\njh"
+ "gfda\njftyuyiugcf\nhfuygihvftyughbuy\nhgyuftydfhgfyc\ndstryrfdts");
ta.setCaretPosition(0);
}
});
add(btn, BorderLayout.SOUTH);
}
}
}
I had a play around with scrollRectToVisible, but ended up having to use SwingUtilites.invokeLater to make it work, for example...
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ta.scrollRectToVisible(new Rectangle(0, 0, 10, 10));
}
});
so I'd say setCaretPosition in this case is the simpler solution
I am a beginner at java so am attempting to create a minesweeper game. I have a grid full of JButtons that when clicked reveal numbers or mines.
I want to add "flags" so when I right click on any button it changes colour - showing it has been flagged and is 'locked' so it cannot be clicked on unless right clicked.
Here are my buttons
public void buttons()
{
// Creating the grid with buttons
grid.setLayout(new GridLayout(20,20));
// Button grid
for (int x = 0; x < buttons.length; x++)
{
for (int y = 0; y < buttons.length; y++)
{
buttons[x][y] = new JButton();
buttons[x][y].addActionListener(this);
grid.add(buttons[x][y]);
}
}
I attempted to create this right click functionality but I am currently stuck and would like some help.
public void flag()
{
buttons.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
JButton rightClick = new JButton("Right Click");
rightClick.addActionListener(this);
}
});
}
Typically, you would process user events on a button via the button's ActionListener, what you want to try and do is stop the user from trigger the buttons ActionListener, the easiest way that you can do this is disable the button...
Normally, I don't like using MouseListeners on buttons as this is not normally the best way to ascertain user interaction, but in this case, it's the requirement
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JButton btn;
public TestPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
btn = new JButton("O");
btn.setMargin(new Insets(8, 8, 8, 8));
add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("You clicked me");
}
});
btn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
btn.setEnabled(!btn.isEnabled());
if (btn.isEnabled()) {
btn.setText("O");
} else {
btn.setText("X");
}
}
}
});
}
}
}
Hi I am trying to make java desk top application where I am using 3 JButtons. I want that when I click any JButton it should change the color of that button and if I click on any other JButton then previous clicked button should be like before and recently clicked button change its color until another JButton is clicked
How can I achieve this
here is my button code
b1 = new JButton("Ok");
b1.setBounds(800, 725, 100, 40);
b1.setForeground(Color.BLACK);
c.add(b1);
b2 = new JButton("Print");
b2.setBounds(925, 725, 100, 40);
b2.setForeground(Color.BLACK);
c.add(b2);
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
b1.setBackground(Color.BLUE);
JOptionPane.showMessageDialog(frame,"Welcome to allhabad High Court");
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
b2.setBackground(Color.BLUE);
JOptionPane.showMessageDialog(frame,"Welcome to allhabad High Court");
}
});
This is actually more tricky then it sounds. Some look and feels don't use the background color property when rendering the buttons (for example Windows)
A possible solution might be to use a ButtonGroup and JToggleButton, which will ensure that only one button is selected at a time and allow you to monitor the selected states of the buttons, for example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ToggleButton {
public static void main(String[] args) {
new ToggleButton();
}
public ToggleButton() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JToggleButton b1 = new JToggleButton("Ok");
b1.setContentAreaFilled(false);
b1.setOpaque(true);
b1.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (b1.isSelected()) {
b1.setBackground(Color.BLACK);
} else {
b1.setBackground(null);
}
}
});
final JToggleButton b2 = new JToggleButton("Print");
b2.setContentAreaFilled(false);
b2.setOpaque(true);
b2.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (b2.isSelected()) {
b2.setBackground(Color.BLUE);
} else {
b2.setBackground(null);
}
}
});
ButtonGroup bg = new ButtonGroup();
bg.add(b1);
bg.add(b2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(b1);
frame.add(b2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Another solution might be to use JRadioButton instead, which is generally used to indicate a single selection from a group of options.
See How to Use Buttons, Check Boxes, and Radio Buttons
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
b1.setBackground(Color.BLUE);
b2.setBackground(Color.BLACK);
JOptionPane.showMessageDialog(frame,"Welcome to allhabad High Court");
}
});
b2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae){
b2.setBackground(Color.BLUE);
b1.setBackground(Color.BLACK);
JOptionPane.showMessageDialog(frame,"Welcome to allhabad High Court");
}
});
For Example:
When JButton1 click JInternalFrame1 Show on the JDesktopPane
And when JButton2 Click JInternalFrame1 Close and JInternalFrame2 Show on the JDesktopPane.
thx before
Edit: with code from comment
if (JInternalFrame1 == null) {
JInternalFrame1 = new FJInternalFrame();
Desktop.add(JInternalFrame1);
JInternalFrame1.toFront();
} else {
JInternalFrame1.dispose();
}
Take a look at this example. I created a custom JInternalFrame that has a different title every time you create a new frame. when you click on the button, a new one is created and the old one disapears
Here is the important code that may help you out. I add a new frame if the desktop size is equal to 0, other wise I remove the previous one, add a new frame, and revalidate
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (desktop.getAllFrames().length == 0) {
desktop.add(new MyInternalFrame());
} else {
desktop.remove(0);
desktop.add(new MyInternalFrame());
revalidate();
repaint();
}
}
});
Here is the complete code. It's two different files.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class InternalFrameDemo1 extends JPanel {
JDesktopPane desktop;
JButton button;
public InternalFrameDemo1() {
desktop = new JDesktopPane();
button = new JButton("Get Next Frame");
setLayout(new BorderLayout());
add(desktop, BorderLayout.CENTER);
add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (desktop.getAllFrames().length == 0) {
desktop.add(new MyInternalFrame());
} else {
desktop.remove(0);
desktop.add(new MyInternalFrame());
revalidate();
repaint();
}
}
});
}
public static void createAndShowGui() {
JFrame frame = new JFrame();
frame.add(new InternalFrameDemo1());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
import javax.swing.JInternalFrame;
public class MyInternalFrame extends JInternalFrame {
static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;
public MyInternalFrame() {
super("Document #" + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
setSize(300,300);
setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
setVisible(true);
}
}