Hello guys,
I just want to ask something if is it possible to remove JMenu.addSeparator() after it is being called? for example in my form there is a menu bar and inside the menu bar lets say there are three JmenuItems and each of it has JMenu.addSeparator(). What i want to do is, if a different user is log in I want to setVisible(false) one of JMenuItem because that particular user in not authorize to use that JMenuItem. The problem is when I setVisible(false) one of the JMenuItem the JMenu.addSeparator() still exist which kinda awkward to watch since there are no JMenuItem exist in the middle of two JMenu.addSeparator(). Hope you can help me with this problem.
Thanks in advance
You have two possible solutions...
You Could...
Remove the contents of the menu and rebuilt it based on what the user can do...
menu.removeAll();
// Add menu items back in...
// Personally, I'd have some method that could return back all
// the JMenuItems that could appear on this menu based on the
// the user...
This would be my preferred solution...
You Could...
Hide/show the menu items based on what the current user can actually do and then remove all the JSeparators that appear next to each other, for example...
Component last = null;
for (Component comp : menu.getComponents()) {
if (comp instanceof JSeparator && last instanceof JSeparator) {
menu.remove(comp);
} else {
last = comp;
}
}
Personally, I know which I would prefer and generally, which would produce consistent results...
I ran into a situation where I had to remove the separator from an existing menu. (Old code and wasn't allowed to refactor the whole mess.)
So I used the idea of MadProgrammer's 2nd solution - but rewrote it to actually work.
Component last = null;
for (int idx = 0; (idx < m_fileMenu.getMenuComponentCount()); idx++) {
Component comp = m_fileMenu.getMenuComponent(idx);
if (comp instanceof JPopupMenu.Separator && last instanceof JPopupMenu.Separator) {
m_fileMenu.remove(comp);
idx--;
} else {
last = comp;
}
}
Related
So I want to have a JMenu Level with three JCheckBoxMenuItem like Easy, normal and expert.
Of course, only one can be checked and if one is checked, it can't be unchecked (enabled(false)) because it's the only one.
I want when one JCheck is checked, all others are unchecked.
So it seems easy, but the only solution I found is to do it with a lot of "if" conditions.
Is there a way to do it with a better algorithm ?
It sounds like you'd be better off using a JRadioButton since check boxes are generally used for multiple-choice options and radio buttons for a single selection out of many. JRadioButtons can be grouped together using a ButtonGroup which allows only one selected at a time.
public void stateChanged(ChangeEvent e) {
if (e.getSource() == cb1 && cb1.isSelected()) {
cb2.setSelected(false);
cb3.setSelected(false);
} else if (e.getSource() == cb2 && cb2.isSelected()) {
cb3.setSelected(false);
cb1.setSelected(false);
} else if (e.getSource() == cb3 && cb3.isSelected()) {
cb1.setSelected(false);
cb2.setSelected(false);
}
}
i just put all my JCheckBoxMenuItems in an array
and every time i select a JCheckBoxMenuItem i call this method
public void clearCheckBoxes(){
for (JCheckBoxMenuItem arrayCB1 : arrayCB) {
if (arrayCB1 != cb) {
arrayCB1.setSelected(false);
} else {
arrayCB1.setSelected(true);
}
}
}
The annoying part was having to manualy put them in the array,maybe the jMenu class has a method that returns the complete array but i didnt bother looking
arrayCB[0]=bridgeCB;
arrayCB[1]=swampCB;
arrayCB[2]=flowerCB;
arrayCB[3]=MountainCB;
arrayCB[4]=Mountain2CB;
arrayCB[5]=forestCB;
arrayCB[6]=parisCB;
arrayCB[7]=roadCB;
arrayCB[8]=waveCB;
arrayCB[9]=lakeCB;
just in case , this is how you create the array
JCheckBoxMenuItem [] arrayCB=new JCheckBoxMenuItem[10];
i dont know about that lots of if statements way of doing it
Is it possible to control whether a column should be available in a column control popup menu? I'm aware of toggling (Disable/enable using CheckBoxList) and gray-out the column. But I do not want column entry in popup menu as The column is must-have column in Jtable. I'm using the JXTable. Anyone that have any hints?
A TableColumnExt has a property hideable which effectly disables the hiding. It is still shown in the popup and you can toggle the checkbox (that's a bug, just filed - the menu item should be disabled ;), but at least the column isn't hidden. To work around the bug, you can implement a custom column control (as Robin correctly suggested) which doesn't add the checkbox, something like:
JXTable table = new JXTable(new AncientSwingTeam());
// here the hideable property is configured manually,
// in production code you'll probably have a custom ColumnFactory
// doing it based on some data state
table.getColumnExt(0).setHideable(false);
ColumnControlButton columnControl = new ColumnControlButton(table) {
#Override
protected ColumnVisibilityAction createColumnVisibilityAction(
TableColumn column) {
if (column instanceof TableColumnExt
&& !((TableColumnExt) column).isHideable())
return null;
return super.createColumnVisibilityAction(column);
}
};
table.setColumnControl(columnControl);
table.setColumnControlVisible(true);
As to not including the menu item: when introducing the hideable property, we decided to go for keeping the item in the list but disable it because users might get confused not seeing all columns in the control. So once the bug will be fixed (just done, committed as of revision #4315), I would recommend to remove the custom column control again. Just my 2 euro-cents, though :-)
ColumnControlButton#createColumnVisibilityAction looks like the method you are looking for. According to the documentation:
Creates and returns a ColumnVisibilityAction for the given TableColumn. The return value might be null, f.i. if the column should not be allowed to be toggled
you can return null for your case.
You should be able to plug this in by using the JXTable#setColumnControl method.
First way:
myTable().getColumnExt(_column_number_).setHideable(false);
This works smooth but has one UI drawback: text in menu is gray and thick is black - bad user experience.
So try to fix it, text will be gray and thick won't be here:
public class MyTable extends JXTable
{
public MyTable(AbstractTableModel model)
{
//first two columns won't be hiddeable
ColumnControlButton controlButton = new ColumnControlButton(this)
{
#Override
protected ColumnControlPopup createColumnControlPopup()
{
return (new NFColumnControlPopup());
}
class NFColumnControlPopup extends DefaultColumnControlPopup
{
#Override
public void addVisibilityActionItems(List<? extends AbstractActionExt> actions)
{
for(int i = 0; i < actions.size(); i++)
{
AbstractActionExt action = actions.get(i);
JCheckBoxMenuItem chk = new JCheckBoxMenuItem(action);
//Disabling unwanted items but they will be still shown for smooth user experience
if(i == 0 || i == 1)
{
chk.setEnabled(false);
chk.setSelected(false);
//chk.setIcon(new ImageIcon(Icons.class.getResource("check.png")));
}
else
{
chk.setSelected(true);
}
chk.addItemListener(action);
super.addItem(chk);
}
}
}
};
this.setColumnControl(controlButton);
}
}
and if you need to hide controls for "show horizontal scrollbar", "pack" and "pack all" add into code:
//remove items for horizontal scrollbar, pack and packall
this.getActionMap().remove("column.horizontalScroll");
this.getActionMap().remove("column.packAll");
this.getActionMap().remove("column.packSelected");
right after calling super(model)
I have a 6 JCheckBoxes in the UI and based one some user operations, I have to change the state of the JCheckBoxes, like enabling,selecting and making it invisible. So, instead of having the code as separate for each JCheckBox, I have used the following code,
Object[] checkBoxCollection = null;
checkBoxCollection = new Object[]{qualityChkBox1, qualityChkBox2, qualityChkBox3, qualityChkBox4, qualityChkBox5, qualityChkBox6};
for (int i = 0; i < checkBoxCollection.length; i++) {
JCheckBox checkBox = (JCheckBox) checkBoxCollection[i];
if (checkBox.getText().equals("Name") || checkBox.getText().equals("RollNo")) {
checkBox.setSelected(true);
} else {
checkBox.setSelected(false);
}
}
Similarly, I have some places in code, where I am keep on changing the state like setSelected(false) and setSelected(true).
Is there any way that I can do more better than this ?
Thanks in advance.
As shown here, you may be able to use EnumSet to define sets that represent coherent states of your model. Then your check boxes can share a common Action that conditions each JCheckBox according to that defined state.
I wonder, if it possible to determine, that user left certain tab. For example, we have 2 tabs: "omg" and "lol". The current tab is omg. I want to know that user switched from "omg" to "lol"
By adding a change listener to the JTabbedPane you will know when the tab selection changes.
Updated: Added tab index tracking
tabbedPane.getModel().addChangeListener(new ChangeListener() {
int lastTabIndex = -1;
public void stateChanged(ChangeEvent e) {
int newIndex = tabbedPane.getSelectedIndex();
if (lastTabIndex == 1 && newIndex == 2) { //or whatever check/combination of checks you would like
//switched from tab 1 to tab 2!
}
//or just check for leaving tab 1
if (lastTabIndex == 1) {
//left tab 1!
}
//etc
lastTabIndex = newIndex;
}
});
I don't have the source I used for this, but I'm pretty sure what I did was extend JTabbedPane and override setSelectedIndex(int). It is called when the index is GOING to be changed to the indicated number, and I used it to validate things on the pane that was going to be left. If your logic does not execute super.setSelectedIndex(int), then you don't leave the pane (which is what I was after).
I got a doubt regarding pre-selecting(setSelectedIndex(index)) an item in a ListBox, Im using Spring + GWT.
I got a dialog that contains a panel, this panel has a FlexPanel, in which I've put a couple ListBox, this are filled up with data from my database.
But this Panel is for updates of an entity in my database, thus I wanted it to pre-select the current properties for this items, allowing the user to change at will.
I do the filling up in the update method of the widget.
I tried setting the selectedItem in the update method, but it gives me an null error.
I've searched a few places and it seems that the ListBox are only filled at the exact moment of the display. Thus pre-selecting would be impossible.
I thought about some event, that is fired when the page is displayed.
onLoad() doesnt work..
Anyone have something to help me out in here?
I really think you can set the selection before it's attached and displayed, but you have to have added the data before you can select an index. If this is a single select box you could write something like this:
void updateListContent(MyDataObject selected, List<MyDataObject> list){
for (MyDataObject anObject : list) {
theListBox.addItem(anObject.getTextToDisplay(), anObject.getKeyValueForList());
}
theListBox.setSelectedIndex(list.indexOf(selected));
}
If this is a multiple select box something like this may work:
void updateListContent(List<MyDataObject> allSelected, List<MyDataObject> list){
for (MyDataObject anObject : list) {
theMultipleListBox.addItem(anObject.getTextToDisplay(), anObject.getKeyValueForList());
}
for (MyDataObject selected : allSelected) {
theMultipleListBox.setItemSelected(list.indexOf(selected), true);
}
}
(Note I haven't actually compiled this, so there might be typos. And this assumes that the selected element(s) is really present in the list of possible values, so if you cant be sure of this you'll need to add some bounds checking.)
I've been happily setting both the values and the selection index prior to attachment so as far as I'm aware it should work. There's a bug however when setting the selected index to -1 on IE, see http://code.google.com/p/google-web-toolkit/issues/detail?id=2689.
private void setSelectedValue(ListBox lBox, String str) {
String text = str;
int indexToFind = -1;
for (int i = 0; i < lBox.getItemCount(); i++) {
if (lBox.getValue(i).equals(text)) {
indexToFind = i;
break;
}
}
lBox.setSelectedIndex(indexToFind);
}
Pre-selection should work also with setValue()-function. Thus, no complicated code is needed.