ARTICLE AD BOX
Can you intercept JToggleButton clicks, making the selected property change conditional? If you add ItemListener or ActionListener, you can't veto the change, it's already happened. Switching the state back would generate an extra event (there should be no events if the click is vetoed).
Use case: the button state corresponds to some external state, e.g. a DB column value. Once the button is clicked, the external state is mutated accordingly, but the request may be unsuccessful for whatever reason. The GUI state must correspond to an actual external state, so it must follow the latter, not the other way around.
Keep in mind the initial selected state of the toggle is set programmatically (according to the external state). That call must not be intercepted. If it was, then on each GUI load there would be an unnecessary request in the described scenario.
Is listening to mouse clicks and consuming the event in case of a "veto" the only way? I hate to listen to mouse clicks, it smells of kludgy design.
If you run the demo, you'll notice this in your console, even before you do any clicking.
Updating external state to true... import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToggleButton; import javax.swing.WindowConstants; import java.awt.Container; public class ToggleButtonDemo { public static void main(String[] args) { Container mainPanel = createMainPanel(); JFrame frame = new JFrame("Toggle Button Demo"); frame.setContentPane(mainPanel); frame.setLocationRelativeTo(null); frame.pack(); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setVisible(true); } private static JPanel createMainPanel() { JPanel panel = new JPanel(); panel.add(toggleButtonPanel()); return panel; } private static JPanel toggleButtonPanel() { JPanel toggleButtonPanel = new JPanel(); toggleButtonPanel.add(createToggleButton()); return toggleButtonPanel; } private static JToggleButton createToggleButton() { JToggleButton toggleButton = new JToggleButton("Toggle me"); toggleButton.setModel(new JToggleButton.ToggleButtonModel() { @Override public void setSelected(boolean b) { // intercepts programmatic calls too, unacceptable if (externalStateUpdated(b)) super.setSelected(b); } }); toggleButton.setSelected(isSelectedInDb()); return toggleButton; } private static boolean externalStateUpdated(boolean requestedSelected) { System.out.printf("Updating external state to %s...\n", requestedSelected); return true; } private static boolean isSelectedInDb() { // assuming it's always true return true; } }Java 8.
