I am looking for a method to prevent a user from hiding certain columns in my grids. I was trying to override Menu createContextMenu(final int colIndex) method of GridView where I find the submenu items that are related to my not-hidable columns and call disable() on them:
...
for (Component menuItem : menu.getItems()) {
String text = ((MenuItem) menuItem).getText();
if (((MenuItem) menuItem).getSubMenu() != null && (text.equals("Columns"))) {
for (Component subMenuItem : ((MenuItem) menuItem).getSubMenu().getItems()) {
String subMenuItemText = ((MenuItem) subMenuItem).getText();
if (<i want this column to be not hidable>) {
subMenuItem.disable();
}
}
}
}
...
It almost works - when the grid is just rendered the menu items that I disabled are greyed out and they don't accept user's input. However it all breaks after some other, not disabled columns are toggled. All of a sudden the disabled menu items become enabled.
I am using GXT 2.2.6.
Thank you!
The reason of the problem is found. Any changes in columns call GXT listeners and eventually restrictMenu method of GridView is called. This overrides all my disable settings. The solution is to add custom listener let GXT' listener do its job and then overwrite the enable/disable settings.
Related
I'm having a problem with Label and TextField placement in a gridpane in response to toggled RadioButtons.
The window will display the same options except for two different labels and text fields which depend on which RadioButton the user has selected.(See images attached).
InHouse RB Selected
Outsourced RB Selected
I added the RadioButton objects to a Toggle Group, then coded the "on actions" to add the "Machine ID" or "Company Name" fields to the GridPane as needed when one of the options is selected.
My problem is that I can only select each option once, and the display of the second option only overlaps the first instance instead of replacing it. If I try to switch back again, I get a runtime error(in Netbeans) about adding the same object twice to the grid.
Any code that I have tried that could remove the node from the display had no affect on the menu's behavior.
ArrayList<Label> typeSpecLabels = new ArrayList<Label>();
ArrayList<TextField>typeSpecFields = new ArrayList<TextField>();
typeSpecLabels.add(machineIDLabel);
typeSpecLabels.add(companyLabel);
typeSpecFields.add(machineIDField);
typeSpecFields.add(companyNameField);
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
typeSpecLabels.add(machineIDLabel);
grid1.add(typeSpecLabels.get(0),0,8,1,1);
grid1.add(typeSpecFields.get(0), 1,8,1,1);
if(outSourceBtn.isArmed() == true){
grid1.getChildren().remove(companyLabel);
grid1.getChildren().remove(companyNameField);
}
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
typeSpecLabels.add(companyLabel);
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
if(outSourceBtn.isArmed() == true){
grid1.getChildren().remove(machineIDLabel);
grid1.getChildren().remove(machineIDField);
}
});
I have heard that I could try using 2 or 3 different scenes(one for each state of the RadioButtons), so I may try that. But if it can be done the way I have coded it so far, I would prefer to do it that way.
I would suggest to remove all type specific labels and fields from your grid and then add ones that you need. So the code will look like following:
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
grid1.getChildren().removeAll(machineIDLabel, companyLabel, machineIDField, companyNameField);
grid1.add(machineIDLabel,0,8,1,1);
grid1.add(machineIDField, 1,8,1,1);
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
grid1.getChildren().removeAll(machineIDLabel, companyLabel, machineIDField, companyNameField);
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
});
This code ended up working, as Pavlo suggested.
Although I just removed the objects specific to the opposing event.
The code works with no errors or overlapping.
inHouseBtn.setOnAction(inHouseSpecificEvent ->
{
grid1.add(machineIDLabel,0,8,1,1);
grid1.add(machineIDField,1,8,1,1);
grid1.getChildren().remove(companyLabel);
grid1.getChildren().remove(companyNameField);
});
outSourceBtn.setOnAction(outSourceSpecificEvent ->
{
grid1.add(companyLabel,0,8,1,1);
grid1.add(companyNameField,1,8,1,1);
grid1.getChildren().remove(machineIDLabel);
grid1.getChildren().remove(machineIDField);
});
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 am working on Java swing application using data base with MySQL
I need to know if I can deactivate components until select an element from JComboBox? I must know the choice of the 1st jcombobox to fill the 2nd JComboBox; the 1st choice is a foreign key on the 2nd, like that :
ResultSet res = st.executeQuery("SELECT NomF FROM famille_de_type");
while (res.next()) {
comboBox_Fam_innewT.addItem(res.getString(1));
}
this is my example :
Of course, you can. When you start work call setEnabled(false) to second comboBox. And add to 1st combobox ItemListener. It will be listen item selection.
firstComboBox.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange()==ItemEvent.SELECTED)
{
Object selectedItem = e.getItem(); // new item selected
// TODO select values for 2nd combobox
// TODO fill 2nd combobox
secondComboBox.setEnabled(true);
}
}
});
So in the ActionListenr of the JComboBox, simply call the setEnabled methods, passing false to disable them, or true to enable them
I need to know if i can deactivate components until select an element from jcombobox ?
YES. Why not Component.SetEnabled(false)?
Also you might want to look at ItemListener interface to achieve your goal. Here is more about Handling Events on a Combo Box.
I am working on a project where I have many radio buttons in several radio groups. What I would like to do is save the configuration of all the radio groups in accordance to a specific button in the first radio group. For example the first radio group is called select and I have 4 different select radio buttons. When I switch from the 4 buttons inside that group I would like the other radio group buttons to be filled in automatically to that of what they were previously, I would also like to save the configuration of the current button when it is switched through out the radio group. So for example if a radio button in the first radio group is switched it remembers the configuration of the previous one and will automatically load itself again when it comes back to that view.
Create a model that models all of this. Use a property change listener (or many other listeners) to allow you to listen for update in state. The state will be updated whenever you call a setter on the model.
For example, when you set the outer radio button group to the 2nd button, then the model can throw property change events for all of the buttons which depend on that state. The getters for the state of the inner radio buttons can depend on the state of the outer button.
You will probably need to add listeners in the view that listen for user actions on the buttons. The actions in these listeners will call the setters on the model. Be careful to not cause recursive events this way.
Example:
This is an example of the model you could build. Say you have an outer radio button group with 2 buttons and single inner button group with 3 buttons. The inner group options are always the same regardless of the selected outer button.
public class Model {
private int outerSelected = 0; // 0 or 1
private InnerModel[] innerModels = new InnerModel[2];
private class InnerModel {
private int selected = 0; // 0, 1, or 2
public void setSelected(int selected) {
this.selected = selected;
// Send event
}
public int getSelected() {
return selected;
}
}
public int getSelectedInnerModel() {
return innerModels[outerSelected];
}
public int setOuterSelected(int outerSelected) {
this.outerSelected = outerSelected;
// send event for selectedInnerModel change
// If you use beans binding, this should cause the view to re-query the
// getSelected on the InnerModel as well
}
}
I wouldn't suggest you actually use integers. The enum is a better idea, but I didn't write it out. Optionally, you can make this Model class be private inside your view.
In my application i have put listfield on the screen. Now my problem is that when i am clicking the list item (while list item has the focus on it) it does activities asopen the menu.
I want to disable the menu while clicking list. I want that if i click the list item it should perform only the necessary task defined in the item click event, Not shown the menu with it.
Any body has some idea about about that?
Override the navigationClick() for your ListField to consume the click event (should return true) without calling super.navigationClick():
protected boolean navigationClick(int status, int time) {
Status.show("Clicked on item: " + myList.getSelectedIndex());
return true;
}