Skip to main content

Any action on Action enhancements?

44 replies [Last post]
uncle_alice
Offline
Joined: 2003-06-16
Points: 0

I particularly want to know if AbstractAction is going to support SELECTED and LARGE_ICON properties. I was expecting them to be added in Tiger, but it didn't happen. I've been looking at some of the relevant bug reports (4133141, 4491747), but they're all still open. Any news?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
zander
Offline
Joined: 2003-06-13
Points: 0

> While you are at it, here is another property that is
> missing. Not frequently used, but the more irritating
> when you need it:
> displayed mnemonic index
> You can specify the mnemonic, so you really should be
> able to also specify the index.
> Classic example:
> [pre]
> Save As
> -[/pre]

Naturally; indexes are hell to translate, so if you take into account the option to translate something having an index separate from the string is not really nice for your translator and surely will make things a LOT harder to keep sane.

I suggest to follow a good idea from my formerly mentioned package that sets strings like this:
Save &As
The & is then filtered out for normal text and the & is used to find the position or next char for buttons to set the mnemonic there.

This idea has proven to work wonders and my software has been translated including mnemonics into many languages, including Chinese (5 dialects)

Scott Violet

Thomas,

Supporting some escape sequence would certainly make things a lot more
straightforward. We didn't have the time in 1.6, but should for 1.7.

-Scott

Scott Violet

For those interested in the 1.6 changes take a look at my recent blog:
http://weblogs.java.net/blog/zixle/archive/2005/11/changes_to_acti.html
. It details all the changes.

-Scott

skelvin
Offline
Joined: 2003-06-11
Points: 0

I'd like to make a comment on storing the selected state in the action:
IMHO it's a bad idea. Buttons can always share the same model to achieve this, that's what models are for.
It's already not the cleanest design to couple view properties and action handling in the same object, but so be it. Now at least do not also bring the model to the mix.

Or maybe I misunderstood something?

skelvin
Offline
Joined: 2003-06-11
Points: 0

While you are at it, here is another property that is missing. Not frequently used, but the more irritating when you need it:
displayed mnemonic index
You can specify the mnemonic, so you really should be able to also specify the index.
Classic example:
[pre]
Save As
-[/pre]

Scott Violet

swing@javadesktop.org wrote:
> While you are at it, here is another property that is missing. Not frequently used, but the more irritating when you need it:
> displayed mnemonic index
> You can specify the mnemonic, so you really should be able to also specify the index.
> Classic example:
> [pre]
> Save As
> -[/pre]

Ask and you shall receive!
It's been done as part of 4133141
(http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4133141).
Here's the complete list of new constants added in 1.6 (available via
http://mustang.dev.java.net now):

/**
* The key used for storing a Boolean that corresponds
* to the selected state. This is typically used only for components
* that have a meaningful selection state. For example,
* JRadioButton and JCheckBox make use of
* this but instances of JMenu don't.
*

* This property differs from the others in that it is both read
* by the component and set by the component. For example,
* if an Action is attached to a JCheckBox
* the selected state of the JCheckBox will be set from
* that of the Action. If the user clicks on the
* JCheckBox the selected state of the
JCheckBox
* and the Action will both be updated.
*

* Note: the value of this field is prefixed with 'Swing' to
* avoid possible collisions with existing Actions.
*
* @since 1.6
*/
public static final String SELECTED_KEY = "SwingSelectedKey";

/**
* The key used for storing an Integer that corresponds
* to the index in the text (identified by the NAME
* property) that the decoration for a mnemonic should be rendered
at. If
* the value of this property is greater than or equal to the length of
* the text, it will treated as -1.
*

* Note: the value of this field is prefixed with 'Swing' to
* avoid possible collisions with existing Actions.
*
* @see AbstractButton#setDisplayedMnemonicIndex
* @since 1.6
*/
public static final String DISPLAYED_MNEMONIC_INDEX_KEY =
"SwingDisplayedMnemonicIndexKey";

/**
* The key used for storing an Icon. This is typically
* used by buttons, such as JButton and
* JToggleButton.
*

* If the same Action is used with menus and buttons
you'll
* typically specify both a SMALL_ICON and a
* LARGE_ICON_KEY. The menu will use the
* SMALL_ICON and the button the
LARGE_ICON_KEY.
*

* Note: the value of this field is prefixed with 'Swing' to
* avoid possible collisions with existing Actions.
*
* @since 1.6
*/
public static final String LARGE_ICON_KEY = "SwingLargeIconKey";

-Scott

skelvin
Offline
Joined: 2003-06-11
Points: 0

> Ask and you shall receive!
Don't tempt me ;-)

Another remark: Can you please make sure that components created with actions not only listen to property changes, but really in fact update all their display properties according to the new values?!

We had to implement live locale switching. (Not terribly usefull, since you do not change the language that often. Still the kind of messages like "please restart" are sort of an anachronism.)
Some properties for some components just did not update.
E.g. the accelerator was not updated on menu items. I am not sure if this is still the case with the latest JDK, but I can try, if you want a definitve error report.

At least for all new properties all components' action listeners should now also update (the displayed mnemonic index etc).

Scott Violet

swing@javadesktop.org wrote:
>>Ask and you shall receive!
>
> Don't tempt me ;-)
>
> Another remark: Can you please make sure that components created with
> actions not only listen to property changes, but really in fact update
> all their display properties according to the new values?!

You should have this covered. That said, if you have specific test cases
I urge you to download the latest and kick the tires.

-Scott

skelvin
Offline
Joined: 2003-06-11
Points: 0

Cool. Thanks a lot. I tested with Mustang from Oct, 13.
It looks much better as in JDK 1.5.0_05 (in that version the mnemonics do not update, in menu items the tooltip does not update - then I stopped testing).

With Mustang everything is fine, with one exception:
For JButton and JMenuItem the selected state does not update (works for radio buttons and check boxes).
You could argue that selection is meaningless for these, but still the selection property is defined already in AbstractButton, so shouldn't it be updated for ALL subclasses?

Here is the test code I wrote, maybe you can make use of it:
[code]import junit.framework.TestCase;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.*;

public class TestActionUpdates extends TestCase {
private ActionProperties propertiesA;
private ActionProperties propertiesB;

protected void setUp() throws Exception {
propertiesA = new ActionProperties("AAA", "a short description", "a action",
KeyStroke.getKeyStroke('A', KeyEvent.CTRL_DOWN_MASK), 'A',
1, new XIcon(), new XIcon(), false, true);
propertiesB = new ActionProperties("B B B", "b short desc", "b command",
KeyStroke.getKeyStroke('B', KeyEvent.SHIFT_DOWN_MASK), 'B',
4, new XIcon(), new XIcon(), true, false);
}

public void testButton() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JButton button = new JButton(action);
propertiesA.checkButton(button);
propertiesB.configureAction(action);
propertiesB.checkButton(button);
propertiesA.configureAction(action);
propertiesA.checkButton(button);
}

public void testCheckBox() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JCheckBox button = new JCheckBox(action);
propertiesA.checkCheckBox(button);
propertiesB.configureAction(action);
propertiesB.checkCheckBox(button);
propertiesA.configureAction(action);
propertiesA.checkCheckBox(button);
}

public void testRadioButton() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JRadioButton button = new JRadioButton(action);
propertiesA.checkRadioButton(button);
propertiesB.configureAction(action);
propertiesB.checkRadioButton(button);
propertiesA.configureAction(action);
propertiesA.checkRadioButton(button);
}

public void testRadioButtonMenuItem() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JRadioButtonMenuItem button = new JRadioButtonMenuItem(action);
propertiesA.checkRadioButton(button);
propertiesB.configureAction(action);
propertiesB.checkRadioButton(button);
propertiesA.configureAction(action);
propertiesA.checkRadioButton(button);
}

public void testCheckBoxMenuItem() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JCheckBoxMenuItem button = new JCheckBoxMenuItem(action);
propertiesA.checkRadioButton(button);
propertiesB.configureAction(action);
propertiesB.checkRadioButton(button);
propertiesA.configureAction(action);
propertiesA.checkRadioButton(button);
}

public void testMenuItem() {
AbstractAction action = new XAbstractAction();
propertiesA.configureAction(action);

JMenuItem button = new JMenuItem(action);
propertiesA.checkMenuItem(button);
propertiesB.configureAction(action);
propertiesB.checkMenuItem(button);
propertiesA.configureAction(action);
propertiesA.checkMenuItem(button);
}

private static class ActionProperties {
private final String name;
private final String shortDescription;
private final String actionCommandKey;
private final KeyStroke accelerator;
private final int mnemonic;
private final int displayedMnemonicIndex;
private final Icon smallIcon;
private final Icon largeIcon;
private final boolean selected;
private final boolean enabled;

public ActionProperties(String name, String shortDescription, String actionCommandKey, KeyStroke accelerator,
int mnemonic, int displayedMnemonicIndex, Icon smallIcon, Icon largeIcon,
boolean selected, boolean enabled) {
this.name = name;
this.shortDescription = shortDescription;
this.actionCommandKey = actionCommandKey;
this.accelerator = accelerator;
this.mnemonic = mnemonic;
this.displayedMnemonicIndex = displayedMnemonicIndex;
this.smallIcon = smallIcon;
this.largeIcon = largeIcon;
this.selected = selected;
this.enabled = enabled;
}

private void configureAction(Action action) {
action.putValue(Action.NAME, name);
action.putValue(Action.SHORT_DESCRIPTION, shortDescription);
action.putValue(Action.ACTION_COMMAND_KEY, actionCommandKey);
action.putValue(Action.ACCELERATOR_KEY, accelerator);
action.putValue(Action.MNEMONIC_KEY, mnemonic);
action.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, displayedMnemonicIndex);
action.putValue(Action.SMALL_ICON, smallIcon);
action.putValue(Action.LARGE_ICON_KEY, largeIcon);
action.putValue(Action.SELECTED_KEY, selected);
action.setEnabled(enabled);
}

private void checkMenuItem(JMenuItem item) {
checkAbstractButton(item, true, false);
assertEquals(accelerator, item.getAccelerator());
}

private void checkButton(AbstractButton button) {
checkAbstractButton(button, true, true);
}

private void checkCheckBox(AbstractButton button) {
checkAbstractButton(button, false, false);
}

private void checkRadioButton(AbstractButton button) {
checkAbstractButton(button, false, false);
}

private void checkAbstractButton(AbstractButton button, boolean hasIcon, boolean usesLargeIcon) {
assertEquals(name, button.getText());
assertEquals(shortDescription, button.getToolTipText());
assertEquals(actionCommandKey, button.getActionCommand());
assertEquals(mnemonic, button.getMnemonic());
assertEquals(displayedMnemonicIndex, button.getDisplayedMnemonicIndex());
if(hasIcon) {
assertEquals(usesLargeIcon ? largeIcon : smallIcon, button.getIcon());
}
assertEquals(selected, button.isSelected());
assertEquals(enabled, button.isEnabled());
}

}

private class XAbstractAction extends AbstractAction {
public void actionPerformed(ActionEvent e) {
}
}

private static class XIcon implements Icon {
public void paintIcon(Component c, Graphics g, int x, int y) {
}

public int getIconWidth() {
return 0;
}

public int getIconHeight() {
return 0;
}
}
}
[/code]

Scott Violet

JButtons don't represent the selection state in any meaningful way,
therefor having the selected state come from the Action is only
implemented for jcheckbox/jradiobutton/jtogglebutton and
jcheckboxmenuitem/jradiobuttonmenuitem.

-Scott

skelvin
Offline
Joined: 2003-06-11
Points: 0

I understand this.
Some arguments against it:
* Ages ago someone decided that AbstractButton has a selection state. So you can set and query the selected state of a JButton. To not introduce any inconsistencies you should stick to that decision.
* Consider a custom button that extends AbstractButton and has a meaningful interpretation of selected state. It would need additional code.

BTW: Wouldn't it be easier to implement to manage selected state in the base class?

Scott Violet

swing@javadesktop.org wrote:
> I understand this.
> Some arguments against it:
> * Ages ago someone decided that AbstractButton has a selection state. So
> you can set and query the selected state of a JButton. To not introduce
> any inconsistencies you should stick to that decision.

All true.

> * Consider a custom button that extends AbstractButton and has a
> meaningful interpretation of selected state. It would need additional code.

Again, all true.

> BTW: Wouldn't it be easier to implement to manage selected state in the base class?

It's actually all implemented in AbstractButton, but enabled by a method
that returns false in AbstractButton. The subclasses that care override
the method to enable it and return true.

I certainly see your points, but is this hypothetical or do you have a
real use case?

Could you file a bug on this?

Thanks,

-Scott

Joshua Marinacci

Hi Alan. I've looked over your new change and I'm trying it out right
now. I'll get back to you after we play around with it. A sample app
would be very helpful. Could you just email me your modified version of
the notepad app directly?

Thanks,
- Joshua

swing@javadesktop.org wrote:

>Okay, the review ID this time is 548392. After moving the "enabled" and SHORT_DESCRIPTION handling out to the components, the actionPropertyChanged method in ActionPropertyChangeListener had nothing to do, so I made it (and the class) abstract. (Should I have changed its name back to [b]Abstract[/b]ActionEtc.?) And there was no point having it return a boolean any more, so I changed that to void.
>
>So each action-enabled component creates its own subclass of ActionPCL, and each subclass implements that method in exactly the same way. It occurs to me that, if those components implemented an interface that specified the callback methods, ActionPCL would be able to call the methods directly and the subclasses could go away. Would that be possible? (Did I just volunteer for more work? :))
>
>I did test these changes, BTW, but I couldn't see how to create a test case that I could include in the submission form. I took the Notepad demo app and updated it to use some of the new features, then I overrode the SHORT_DESCRIPTION handling as I described earlier: only toolbar buttons display tooltips, and the tooltips include the accelerator if there is one. The tooltips for the Undo and Redo actions change to reflect the UndoManager's state whenever the document is edited, so both callback methods get used.
>
>The nicest part was the line-wrapping actions. They keep track of their own selection status, so when I created the toolbar buttons and menuitems for them, I didn't bother using ButtonGroups, and they worked fine. Admittedly, this was the simplest possible case, where one of the items is always selected, and clicking on the selected item doesn't deselect it. But I believe having selection support in the action framework eliminates the need for ButtonGroup entirely (but then, I've never liked ButtonGroup).
>
>-Alan
>---
>[Message sent by forum member 'uncle_alice' (Alan Moore)]
>
>http://www.javadesktop.org/forums/thread.jspa?messageID=117009
>
>

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

> Could you just email me your modified version of
> the notepad app directly?

Done (I hope). Let me know if you didn't get it.

Joshua Marinacci

Correct. A full set of diffs would be best. Then I can apply them all at
once as a single change.
Thanks,
- Joshua
swing@javadesktop.org wrote:

>>Could you submit diffs for exactly what you would like to see?
>>
>>
>
>Will do. I guess these diffs should include the changes from the first set I submitted (so this RFE replaces the first one), right?
>
>-Alan
>---
>[Message sent by forum member 'uncle_alice' (Alan Moore)]
>
>http://www.javadesktop.org/forums/thread.jspa?messageID=116733
>
>

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Okay, the review ID this time is 548392. After moving the "enabled" and SHORT_DESCRIPTION handling out to the components, the actionPropertyChanged method in ActionPropertyChangeListener had nothing to do, so I made it (and the class) abstract. (Should I have changed its name back to [b]Abstract[/b]ActionEtc.?) And there was no point having it return a boolean any more, so I changed that to void.

So each action-enabled component creates its own subclass of ActionPCL, and each subclass implements that method in exactly the same way. It occurs to me that, if those components implemented an interface that specified the callback methods, ActionPCL would be able to call the methods directly and the subclasses could go away. Would that be possible? (Did I just volunteer for more work? :))

I did test these changes, BTW, but I couldn't see how to create a test case that I could include in the submission form. I took the Notepad demo app and updated it to use some of the new features, then I overrode the SHORT_DESCRIPTION handling as I described earlier: only toolbar buttons display tooltips, and the tooltips include the accelerator if there is one. The tooltips for the Undo and Redo actions change to reflect the UndoManager's state whenever the document is edited, so both callback methods get used.

The nicest part was the line-wrapping actions. They keep track of their own selection status, so when I created the toolbar buttons and menuitems for them, I didn't bother using ButtonGroups, and they worked fine. Admittedly, this was the simplest possible case, where one of the items is always selected, and clicking on the selected item doesn't deselect it. But I believe having selection support in the action framework eliminates the need for ButtonGroup entirely (but then, I've never liked ButtonGroup).

-Alan

Scott Violet

Hi Alan,

swing@javadesktop.org wrote:
> Okay, the review ID this time is 548392. After moving the "enabled" and
> SHORT_DESCRIPTION handling out to the components, the
> actionPropertyChanged method in ActionPropertyChangeListener had nothing
> to do, so I made it (and the class) abstract. (Should I have changed its
> name back to [b]Abstract[/b]ActionEtc.?) And there was no point having
> it return a boolean any more, so I changed that to void.

That seems reasonable to me.

> So each action-enabled component creates its own subclass of ActionPCL,
> and each subclass implements that method in exactly the same way. It
> occurs to me that, if those components implemented an interface that
> specified the callback methods, ActionPCL would be able to call the
> methods directly and the subclasses could go away. Would that be
> possible? (Did I just volunteer for more work? :))

That would be nice, but if we went the interface route the method would
have to be public. It should be protected.

> I did test these changes, BTW, but I couldn't see how to create a test
> case that I could include in the submission form. I took the Notepad
> demo app and updated it to use some of the new features, then I overrode
> the SHORT_DESCRIPTION handling as I described earlier: only toolbar
> buttons display tooltips, and the tooltips include the accelerator if
> there is one. The tooltips for the Undo and Redo actions change to
> reflect the UndoManager's state whenever the document is edited, so both
> callback methods get used.

It would be best to write an automated test. When I redid this code I
wrote one, I'll make sure it still works.

> The nicest part was the line-wrapping actions. They keep track of their
> own selection status, so when I created the toolbar buttons and
> menuitems for them, I didn't bother using ButtonGroups, and they worked
> fine. Admittedly, this was the simplest possible case, where one of the
> items is always selected, and clicking on the selected item doesn't
> deselect it. But I believe having selection support in the action
> framework eliminates the need for ButtonGroup entirely (but then, I've
> never liked ButtonGroup).
>

:)

-Scott

Scott Violet

Uncle_Alice,

swing@javadesktop.org wrote:
> Been away for a while, but yes, #4133141 covers all the enhancements
> I've been wanting to see: large icons, selection state, and mnemonic
> indexes. I don't know about arbitrarily using the large icon for
> non-menuitem buttons, though; does that mean it will be impossible to
> use small icons if large ones are available?

For non-menuitems, yes, that is correct. Although you could always
override the configure methods and the PropertyChangeListener.

> And what if some actions
> have large icons but others don't?

Large is used if non-null, otherwise small.

> When you add them all to a JToolbar,
> will they show up as a mix of large and small buttons? There's a good
> chance the developer won't have any control over which icons are
> available at runtime, but we still have to ensure that the app does
> something sensible.
>
> I agree that ActionListeners shouldn't be notified when a button is
> selected programmatically; that should only happen in response to a
> button press.

:)

> Is the reconfigureOnNull property really necessary? Why not just make
> that the default behavior?

I wasn't sure that developers are using null to mean they want
everything reread. I've seen apps that use null as a hack for
notification of properties that aren't properties. As such, I was
worried about making it the default.

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Scott,

> For non-menuitems, yes, that is correct.
> Although you could always override
> the configure methods and the
> PropertyChangeListener.

So how difficult is that going to be? Currently, some of the methods/classes involved are inconveniently private--probably the second most common complaint people have about the action framework.

Zander,

Good point: the act of setting the selection state can't be completely divorced from the firing of action events (however much we might like to). Your approach looks as good as anything I've seen.

--Alan

Scott Violet

swing@javadesktop.org wrote:
> Scott,
>
>
>>For non-menuitems, yes, that is correct.
>>Although you could always override
>>the configure methods and the
>>PropertyChangeListener.
>
>
> So how difficult is that going to be? Currently, some of the
> methods/classes involved are inconveniently private--probably the second
> most common complaint people have about the action framework.

Alan,

It's as difficult as it has always been:(

If you file an RFE I'll open up the API to make it much simpler to
subclass just the configure method and a callback for when the Action
changed in some way.

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

I've just been looking at the source code from Mustang-b52, and I see you've already made significant changes. I assume you're talking about the configurePropertiesFromAction() and actionPropertyChanged() methods in AbstractButton. If the latter method were protected instead of package-private, hacking the properties would be a breeze. It would probably also help if it returned a boolean like the equivalent method in ActionPropertyChangeListener. I'll get to work on that RFE.

--Alan

Scott Violet

Hi Alan,

swing@javadesktop.org wrote:
> I've just been looking at the source code from Mustang-b52, and I see
> you've already made significant changes.

Yep, much of the code was rewritten to make it easier to maintain and use.

> I assume you're talking about
> the configurePropertiesFromAction() and actionPropertyChanged() methods
> in AbstractButton.

Those would be the ones:) configurePropertiesFromAction is protected
already, so I suspect you're really just asking for
actionPropertyChanged to be protected too. Is that right?

> If the latter method were protected instead of
> package-private, hacking the properties would be a breeze. It would
> probably also help if it returned a boolean like the equivalent method
> in ActionPropertyChangeListener. I'll get to work on that RFE.

If you've already downloaded the code might I suggest you send in diffs
for what you would like via the mustang.dev.java.net site? That will
put a priority on the changes. I would suggest you wait a week though.
The displayed mnemonic index, selected state and large icon keys have
not been promoted to the web yet. They'll be in b53.

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

> configurePropertiesFromAction is protected
> already, so I suspect you're really just asking for
> actionPropertyChanged to be protected too. Is that
> right?

Right.

> If you've already downloaded the code might I suggest
> you send in diffs for what you would like via the
> mustang.dev.java.net site? That will put a priority
> on the changes. I would suggest you wait a week though.
> The displayed mnemonic index, selected state and
> large icon keys have not been promoted to the web yet.
> They'll be in b53.

Will do.

--Alan

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Okay, the review ID is 543463. All I did was ask for the visibility of the actionPropertyChanged() method to be changed to "protected" (on reflection, I decided adding a boolean return type would be more confusing than useful). However, it still won't be possible to override the handling of the "enabled" and SHORT_DESCRIPTION properties that way; ActionPropertyChangeListener handles those, never even calling the component's own actionPropertyChanged() method.

In my own action framework, I've customized the handling of both those properties. A toolbar button's tooltip text consists of the short description PLUS a string representation of the action's accelerator, if it has one (just like a menuitem's label). Dialog buttons (i.e., buttons with text-only labels), menuitems and textfields have no tooltips (I think a tooltip is annoyingly redundant in those cases--if more explanation is needed, that's what the long description and the status bar are for).

I override the handling of the "enabled" property only in the case of JTextField. I have a regex-based search-and-replace component, in which the Search action is associated with the Search textfield as well as with a button (so I can type in a search espression and press Enter to execute the search). If the search expression is not a valid regex, the action is disabled--but if the textfield is disabled, how can I fix the regex? Instead, I use a boolean to keep track of the action's enabled state; if it's false, the Enter key is just ignored.

So, as neat as the current handling of those two properties is, I really think the components themselves should be handling them. Would I need to submit another RFE for that?

Scott Violet

Alan,

I was a bit worried about this too. I had ActionPropertyChangeListener
handle all the logic to avoid duplication. When opening up the API I
agree that it makes more sense to always callback to the Component.

Could you submit diffs for exactly what you would like to see?

-Scott

swing@javadesktop.org wrote:
> Okay, the review ID is 543463. All I did was ask for the visibility of the actionPropertyChanged() method to be changed to "protected" (on reflection, I decided adding a boolean return type would be more confusing than useful). However, it still won't be possible to override the handling of the "enabled" and SHORT_DESCRIPTION properties that way; ActionPropertyChangeListener handles those, never even calling the component's own actionPropertyChanged() method.
>
> In my own action framework, I've customized the handling of both those properties. A toolbar button's tooltip text consists of the short description PLUS a string representation of the action's accelerator, if it has one (just like a menuitem's label). Dialog buttons (i.e., buttons with text-only labels), menuitems and textfields have no tooltips (I think a tooltip is annoyingly redundant in those cases--if more explanation is needed, that's what the long description and the status bar are for).
>
> I override the handling of the "enabled" property only in the case of JTextField. I have a regex-based search-and-replace component, in which the Search action is associated with the Search textfield as well as with a button (so I can type in a search espression and press Enter to execute the search). If the search expression is not a valid regex, the action is disabled--but if the textfield is disabled, how can I fix the regex? Instead, I use a boolean to keep track of the action's enabled state; if it's false, the Enter key is just ignored.
>
> So, as neat as the current handling of those two properties is, I really think the components themselves should be handling them. Would I need to submit another RFE for that?
> ---
> [Message sent by forum member 'uncle_alice' (Alan Moore)]
>
> http://www.javadesktop.org/forums/thread.jspa?messageID=115403

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

> Could you submit diffs for exactly what you would like to see?

Will do. I guess these diffs should include the changes from the first set I submitted (so this RFE replaces the first one), right?

-Alan

Scott Violet

swing@javadesktop.org wrote:
>>Could you submit diffs for exactly what you would like to see?
>
>
> Will do. I guess these diffs should include the changes from the first set I submitted (so this RFE replaces the first one), right?

Yep!

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Been away for a while, but yes, #4133141 covers all the enhancements I've been wanting to see: large icons, selection state, and mnemonic indexes. I don't know about arbitrarily using the large icon for non-menuitem buttons, though; does that mean it will be impossible to use small icons if large ones are available? And what if some actions have large icons but others don't? When you add them all to a JToolbar, will they show up as a mix of large and small buttons? There's a good chance the developer won't have any control over which icons are available at runtime, but we still have to ensure that the app does something sensible.

I agree that ActionListeners shouldn't be notified when a button is selected programmatically; that should only happen in response to a button press.

Is the reconfigureOnNull property really necessary? Why not just make that the default behavior?

zander
Offline
Joined: 2003-06-13
Points: 0

Hi uncle alice, I just picked your reply; but I could have gotten any;

> I agree that ActionListeners shouldn't be notified
> when a button is selected programmatically; that
> should only happen in response to a button press.

As you may have read earlier this thread; I have been using a solution similar to what you guys are (partially) reinventing here.
It is my experience that programmatically setting the new state sometimes makes you want to execute the action in the case of toggle actions (checkboxes).
This is because to set the new state will only execute the action if the new state is different from the old one (if the togglebutton or checkbox is toggled or not). You can emulate this by reading the state beforehand, but I found it easier to have:
[code]
public void setSelected(boolean on);
and
public void setSelected(boolean on, boolean silent);
[/code]
see API http://uic.sourceforge.net/api/uic/model/UICToggleAction.html

As I have build a wide array of GUIs with these already, I hope you will take my advice to be based on experience.

abies
Offline
Joined: 2003-06-10
Points: 0

Well, big icon support is hardly a showstopper - as far as I understand it is just a problem of changing your

new JToolBar()

to

new JToolBar() {
protected JButton createActionComponent(Action a) {
JButton jb = super.createActionComponent(a);
Icon big = (Icon)a.getValue("BigIcon");
if ( big != null ) {
jb.setIcon(big);
}
}
}

Sure, having this in JDK would be nice, but I hardly see it as a 'big issue' for people working with toolbars.
('BigIcon' should be of course some constant in your app).

Scott Violet

Artur,

You can certainly work around having a big icon, as you can all of the
other requests here.

> new JToolBar() {
> protected JButton createActionComponent(Action a) {
> JButton jb = super.createActionComponent(a);
> Icon big = (Icon)a.getValue("BigIcon");
> if ( big != null ) {
> jb.setIcon(big);
> }
> }
> }

This actually won't work though. JToolBar.add(Action) calls
createActionComponent, then sets the Action on the button. As such, the
big icon you have set will be replaced with the small icon. Similarly
if the small icon changed in the action, the button would fallback to
the small icon.

That said, you can work around all this, it just requires overriding a
number of methods on JButton.

I hope to have an update on new support in 1.6 for actions in the next
week or two.

-Scott

pietschy
Offline
Joined: 2003-06-10
Points: 0

Hi Scott, this is just a thought, but you might also want to consider adding a text alignment (ie leading and trailing) property to the action as well. I know it's a little obscure, but it's useful for actions like "Next" and "Previous".

Cheers
Andrew

Scott Violet

Andrew,

Interesting idea. Text alignment seems rather specific to the view
(button), and not the action itself.

-Scott

pietschy
Offline
Joined: 2003-06-10
Points: 0

Ahh yep, I was only thinking about buttons (and had forgotten menus).

Thanks
Andrew

Scott Violet

swing-feedback@javadesktop.org wrote:

> I particularly want to know if AbstractAction is going to support
> SELECTED and LARGE_ICON properties. I was expecting them to be added
> in Tiger, but it didn't happen. I've been looking at some of the
> relevant bug reports
>
([url=http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4133141]4133141[/url],
>
[url=http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4491747]4491747[/url]),
> but they're all still open. Any news?

Have you taken a look at JDNC? I believe a bunch of actions related
work has gone on there.

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Yes, I've been watching JDNC, but I was hoping some of the most basic enhancements would be made directly to the Swing classes, e.g., Action and AbstractButton. It shouldn't be necessary to adopt a whole framework like JDNC just to have buttons and menuitems share selection state, or to have buttons use large icons while menuitems use small ones.

Scott Violet

Thanks for the feedback!

4133141 certainly has a high number of votes. I'll see what we can do
for 1.6.

-Scott

jansan
Offline
Joined: 2005-02-24
Points: 0

I just want to emphasize that is a rather important feature for many applications. If making Swing easier to work with is one of the main targets for Mustang, this is a good enhancement to start with.

Yes, there are workarounds, and maybe JNDC has this functionality, but the time of most developers is limited, and if they have to spend one day for finding a solution for this problem (downloading and understanding JNDC can take easily one day) that very day may be missing for adding some important features. And if the same happens for other issues, there will be not much time left to do the real programming because all the time is spent on implementing workarounds or evaluating third party products.

Actually I only wanted to keep this thread alive to make sure that we will not see a comment like "This is too late for Mustang now because we cannot do any API changes anymore, commit to Elephant (or whatever the next JDK version will be)".

Scott Violet

Are the two bugs you've added the ones you want to see fixed?

Thanks,

-Scott

jansan
Offline
Joined: 2005-02-24
Points: 0

I am not the one who started this thread (and mentioned the two bugs), but I think the two RFEs (adding support for selection state and adding support for a second, larger icon) are the two big issues for anybody who is using toolbars in his/her application. Yes, having them fixed would definately be a great improvement, for beginners and advanced developers. If you ask me, the selectable state support is more important (and there are more votes for that issue), the other one is more a nice to have thing (just my opinion).

Thanks for taking this serious, Scott.

zander
Offline
Joined: 2003-06-13
Points: 0

> Yes, having them fixed would definately
> be a great improvement, for beginners and advanced
> developers. If you ask me, the selectable state
> support is more important (and there are more votes
> for that issue), the other one is more a nice to have
> thing (just my opinion).

Since the bugs have been open for some years, an alternative implementation providing this and many many more features might be a good alternative for you to use right now.
The open source (and thus free) software at http://uic.sf.net provides so called UICAction object and an ActionFactory to make gui building easier.
The snapshots (see download page) also provide things like toggle-actions as is requeted in one of the RFEs.

Hope this helps.

Scott Violet

Jan and all,

So I'm trying to get this into mustang so that you don't have to wait
for the elephant release and want some feedback. Supporting a
SELECTED_KEY is a bit different than the other keys in that it'll be two
way. In particular when the selected state of the button changes the
SELECTED_KEY property will need to be updated on the Action, and when
the Action's SELECTED_KEY property changes the button will need to
update it's selected state.

My question comes in as to what should happen to the button when the
Action's SELECTED_KEY property changes. The selected state of the
button will certainly need to change, but should ActionListeners be
notified? If we just do button.setSelected(xxx) it means any
ActionListeners won't be notified. What do you folks expect? Would you
expect ActionListeners to be notified too?

Thanks,

-Scott

pietschy
Offline
Joined: 2003-06-10
Points: 0

Hi Scott, since no one has answered I'll throw in my 2c's worth.

I think it would be preferable if programatically altering the selected state _doesn't_ fire action listeners.

From memory the JComboBox has an issue where calling a setter results in a listener being invoked (that would normally only be notified on a user click). This means you have to remove and listeners before programatically setting the value, which is very annoying (c:

Cheers
Andrew

Scott Violet

Andrew,

Thanks for the vote. This is the directly I've taken.

-Scott