Reputation: 167
I'm trying to create a program where a JButton
will only be enabled if all the JCheckBoxes
are Checked, But I'm having problem with enabling the specific JButton
because once I checked all the JCheckBoxes
the only JButton
being enabled is the last created
Here's my code:
public class Practice extends JFrame implements ActionListener
{
JPanel main=new JPanel();
JPanel gui=new JPanel();
JButton btnadd=new JButton("Add Timer");
JPanel order=new JPanel();
JPanel chkPanel=new JPanel();
JButton remove=new JButton("Remove");
public Practice()
{
main.setLayout(new BorderLayout());
gui.setLayout(new FlowLayout());
main.add(btnadd, BorderLayout.NORTH);
main.add(gui,BorderLayout.CENTER);
add(main);
btnadd.addActionListener(new ActionListener()
{
int ctr=0;
@Override
public void actionPerformed(ActionEvent e)
{
ctr+=1;
//addPanel();
//System.out.print(x);
addPanel(ctr);
revalidate();
repaint();
}
});
main.add(gui);
}
public void addPanel(int ctr)
{
Border blackline=BorderFactory.createLineBorder(Color.BLACK);
order=new JPanel();
order.setPreferredSize(new Dimension(200,300));
order.setLayout(new BorderLayout());
TitledBorder title=BorderFactory.createTitledBorder(blackline);
title.setTitleJustification(TitledBorder.LEFT);
order.setBorder(title);
addCheckPanel(ctr);
addBtn();
gui.add(order);
}
public void addCheckPanel(int ctr)
{
chkPanel=new JPanel();
chkPanel.setLayout(new BoxLayout(chkPanel, BoxLayout.Y_AXIS));
for(int i=0;i<ctr;i++)
addCheck(ctr);
order.add(chkPanel);
}
int y;
public void addCheck(int ctr)
{
JCheckBox check=new JCheckBox("Check Me");
chkPanel.add(check);
y=ctr;
check.addActionListener(listener);
public void addBtn()
{
remove=new JButton("Remove");
order.add(remove, BorderLayout.SOUTH);
remove.setEnabled(false);
remove.addActionListener(listener);
}
public static void main(String args[])
{
TimerPractice p=new TimerPractice();
p.setSize(1000,800);
p.setVisible(true);
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.setLocationRelativeTo(null);
}
ActionListener listener=new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Object source = e.getSource();
if (source instanceof Component)
{
Component comp = (Component)source;
gui.remove(comp.getParent());
revalidate();
repaint();
}
}
};
@Override
public void actionPerformed(ActionEvent e)
{
}
}
Upvotes: 1
Views: 1121
Reputation: 347244
You need to isolate and separate your units of work. For example, your order
panel has controls and functionality, which would be better separated into it's own class, where it can maintain it's own state independently of other instances of itself, for example...
You could pull much of the code of your main class and create a separate class, for example OrderPane
...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class OrderPane extends JPanel {
private JPanel chkPanel;
private int selectedCount = 0;
private int checkCount = 0;
private JButton removeButton;
public OrderPane(int checkCount) {
setLayout(new BorderLayout());
Border blackline = BorderFactory.createLineBorder(Color.BLACK);
TitledBorder title = BorderFactory.createTitledBorder(blackline);
title.setTitleJustification(TitledBorder.LEFT);
setBorder(title);
this.checkCount = checkCount;
addCheckPanel();
addBtn();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 300);
}
public void addCheckPanel() {
chkPanel = new JPanel();
chkPanel.setLayout(new BoxLayout(chkPanel, BoxLayout.Y_AXIS));
for (int i = 0; i < checkCount; i++) {
addCheck();
}
add(chkPanel);
}
public void addCheck() {
JCheckBox check = new JCheckBox("Check Me");
chkPanel.add(check);
check.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JCheckBox cb = (JCheckBox) e.getSource();
if (cb.isSelected()) {
selectedCount++;
} else {
selectedCount--;
}
if (selectedCount == checkCount) {
removeButton.setEnabled(true);
}
}
});
}
public void addBtn() {
removeButton = new JButton("Remove");
add(removeButton, BorderLayout.SOUTH);
removeButton.setEnabled(false);
removeButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof Component) {
Component comp = (Component) source;
Component myParent = comp.getParent();
Container yourParent = myParent.getParent();
yourParent.remove(myParent);
yourParent.revalidate();
yourParent.repaint();
}
}
});
}
}
You would, when needed, create a new instance of this class and add it to you UI as required, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Practice extends JFrame {
JPanel main = new JPanel();
JPanel gui = new JPanel();
JButton btnadd = new JButton("Add Timer");
public Practice() {
main.setLayout(new BorderLayout());
gui.setLayout(new FlowLayout());
main.add(btnadd, BorderLayout.NORTH);
main.add(gui, BorderLayout.CENTER);
add(main);
final Random rnd = new Random();
btnadd.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
OrderPane orderPane = new OrderPane(rnd.nextInt(10));
gui.add(orderPane);
gui.revalidate();
gui.repaint();
}
});
main.add(gui);
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
Practice p = new Practice();
p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.setSize(800, 600);
p.setLocationRelativeTo(null);
p.setVisible(true);
}
});
}
}
You might find some of the information from Object-Oriented Programming Concepts and Inheritance of use and no offense, I would understand these topics before tackling something as complex as a UI ;)
Normally, I would pass some kind of "controller" interface
to the OrderPane
, which would provide the functionality for removing the component from the main UI and other functionality that the OrderPane
might need in order to provide feedback.
Some of this feedback could be provided via a observer/listener pattern, such as when the timer times out, it would be better to provide some kind event back to registered listeners then perhaps calling a method on the "controller" - IMHO
...but lets deal with one concept at a time...
Upvotes: 2