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);
});
Related
I'm struggling with ZK Framework Combobox UI rendering. I have a combobox with 2 logical lists (1 is a short version of 2, with "Show more" option, and 2 is a list with all entries and no "Show more" option). I've done some list swapping logic tracked by onClick event of "Show more" option. And when I click this option combobox closes and than I need to re-open it to see the full list. So my question is do anyone know a way how to keep combobox opened when I click this specific option (and furthermore, dynamically populate model by another list)? Maybe there are any other best practices of how to do the task more efficiently? Thanks everyone for help
I have a thought about combobox that enables multiple choice — it doesn't close when some option is clicked, but I haven't found any related information. Maybe you could make your suggestions about it
The behavior you want "clicking 'show more' and keep the popup open" is not supported by default.
So you have to override its js widget's doClick_(), please read
https://www.zkoss.org/wiki/ZK_Client-side_Reference/General_Control/Widget_Customization
here is an example.
<zscript><![CDATA[
ListModelList fullModel = new ListModelList(Locale.getAvailableLocales());
ListModelList model1 = new ListModelList(fullModel.subList(0, 2));
model1.add("show more");
]]></zscript>
<combobox id="box" model="${model1}" readonly="true" onSelect="loadAll()"/>
<script src="comboitem-doclick.js"/>
<zscript><![CDATA[
public void loadAll(){
if (model1.getSelection().iterator().next().equals("show more")){
box.setModel(fullModel);
box.setValue("");
}
}
]]></zscript>
/**
* Purpose: when a user selects a specific item, keep the popup open.
* Based on version: 9.6.3
*/
zk.afterLoad('zul.inp', function() {
var exWidget = {};
zk.override(zul.inp.Comboitem.prototype, exWidget, {
doClick_: function doClick_(evt) {
if (!this._disabled) {
var cb = this.parent;
cb._select(this, {
sendOnSelect: true,
sendOnChange: true
});
this._updateHoverImage();
if (this.getLabel() != 'show more'){
cb.close({
sendOnOpen: true,
focus: true
}); // Fixed the onFocus event is triggered too late in IE.
}
cb._shallClose = true;
if (zul.inp.InputCtrl.isPreservedFocus(this)) zk(cb.getInputNode()).focus();
evt.stop();
}
},
});
});
Creating a really basic Memory game using Java Swing. I created my GUI with a list of blank buttons where I set the icon property to none.
My code for some of the buttons is:
private void tbtnCard3ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard3.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard5.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard4ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard4.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card7EWaste.png")));
if(tbtnCard7.isSelected()){
score++;
lblScore.setText(""+score);
}
}
private void tbtnCard5ActionPerformed(java.awt.event.ActionEvent evt) {
tbtnCard5.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Card3Logo.png")));
if(tbtnCard3.isSelected()){
score++;
lblScore.setText(""+score);
}
}
I have about 20 toggle buttons and for example the code above works and the scores go up by 1 when a match is found. So for tbtnCard3, if tbtnCard5 is selected the score goes up by 1. Now my question is how would I make it so that if tbtnCard3 is selected but tbtnCard 5 is not selected, display "Wrong Match". Since im using if Selected I'm not too sure how to display "wrong match" when the case is false. It doesn't make sense to say else ifSelected as no parameters can be put either....
In my opinion, the OPs suggestion is not a good approach. You do not want the listener of one button to be "aware" of some other component unnecessarily. Suppose you have an 8-by-8 grid with toggle buttons. You don't want each toggle button listener to be aware of the other 63 toggle buttons.
I believe there is a much simpler (and cleaner) approach. What you want is for the toggle button listener to register and deregister the toggle when the state of the button changes. Let say, you add the toggle button to or remove from a list (most likely a custom class) where you can trigger some logic when the list size reaches two. Then, depending on the outcome of the comparison, it will count a match (and disable these two toggle buttons in the current state), or will display some message like "Try again" and then toggle the buttons to hide the image.
In pseudocode, this will look something like this:
public class ToggleListener implements ItemListener {
public void actionPerformed (ItemEvent event) {
JToggleButton button = (JToggleButton) event.getSource();
if (event.getStateChange()==ItemEvent.SELECTED) {
// TODO Add the button to your list..
} else {
// remove button
}
}
}
In your Swing application, you can create a single instance of the above listener and add it to every single toggle button. And, as you can see, this listener is only responsible to register and unregister the component associated with the triggered event.
The "List Listener" on the other hand, is responsible to trigger the comparison logic when the size of the list reaches two. So, if you click on the same toggle button over and over again, the only thing the button listener will do is add or remove the button from the list depending on the button's current state. However, once a second button is toggled to reveal its image, the list listener will trigger the comparison logic. I am not 100% sure, but I think you could use JavaFX ObservableList interface or one of its implementing classes to do this. If the ListChangeListener.Change class is not suitable to figure out the size of the list to trigger the logic, you will have to implement this on your own. Regardless, in pseudocode, you need to do something like this:
public void onListChange(Event event) {
if (list.size() == 2 && btn1.getIconName().equals(btn2.getIconName())) {
displayMatchMessage();
btn1.setEnabled(false);
btn2.setEnabled(false);
list.clear(); // you should remove matched items from list manually
} else {
displayMismatchMessage();
btn1.setSelected(false); // flip the card
btn2.setSelected(false); // flip the card
// list.clear(); // you should not need this because the setSelected should trigger the Item Listener which should remove item from list.
}
}
Doing something like this is a much cleaner implementation where the button listener have a single job to do and the "list listener" has another job to do. Neither one encroaches on the other's job.
I have a checkboxgroup which has multiple checkboxes. I have certain checkboxes which needs to look different, either by bold text or colored text ,which wont change irrespective of selection/unselection.
I have following code to build checkboxgroup. But I am not able to put style specific to one checkbox, because I dont have access to it. How can I do that
CheckBoxGroup<ReferenceScreenResultAnswer> answersOptionGroup = new CheckBoxGroup<>(question.getText());
List<ReferenceScreenResultAnswer> checkBoxItems = new ArrayList<>();
answersOptionGroup.setItems(checkBoxItems);
.......
// this is where i want to put CSS to specific checkbox/values
for (Answer answer : preSelectedAnswer)
{
ReferenceScreenResultAnswer rsra = new ReferenceScreenResultAnswer();
rsra.setAnswer(answer);
rsra.setReferenceScreenResultQuestion(rsrq);
answersOptionGroup.select(rsra);
}
I can do invidiual checkboxes like
CheckBox cb = new CheckBox();
cb.setCaptionAsHtml(true);
cb.setCaption("<b> hello </b> there");
But I am not able to access individual checkboxes from CheckBoxGroup. Any idea how to access them
i found the answer:
// css style the pre selected answer, so they look different irrespective
// of their selection
answersOptionGroup.setItemCaptionGenerator(new ItemCaptionGenerator<ReferenceScreenResultAnswer>()
{
#Override
public String apply(ReferenceScreenResultAnswer item)
{
if (preSelectedAnswer.contains(item.getAnswer()))
return "<strong>" + item.getAnswer().toString() + "</strong>";
else
return item.getAnswer().toString();
}
});
I need to do something every time the user tries to drag a CheckBox and paste it from one panel to another.
I know Java offers drag and drop API but I don't exactly want the check box to be dragged from one panel to another.
What I want is to give the user an illusion of drag and drop and behind the scenes I want my code running and performing certain operations. How should I do that ??
Now when I drag and drop the check Box image1 from panelleft to panel_right I want certain code to run in the background on that drag and drop action of the user
for(ResourceListObject currentImage : imageList ){
imageOnRepositoryCheckBox[checkBoxNumber] = new JCheckBox(currentImage.getName());
imageOnRepositoryCheckBox[checkBoxNumber].setBounds(6, gapping+checkBoxNumber*26, 368, 23);
imageOnRepositoryCheckBox[checkBoxNumber].setTransferHandler(new FromTransferHandler());
if(imagesToBeImported != null){
if(imagesToBeImported.contains(currentImage)){
imageOnRepositoryCheckBox[checkBoxNumber].setForeground(Color.GRAY);
imageOnRepositoryCheckBox[checkBoxNumber].setToolTipText("This image is already on the list of images to be imported and can't be selected again.");
}
}
panel.add(imageOnRepositoryCheckBox[checkBoxNumber]);
checkBoxNumber++;
}
and the second piece of code that would run is
for(JCheckBox currentCheckBox : imageOnRepositoryCheckBox){
if(currentCheckBox.isSelected()){
Iterator itr = imagesOfCurrentRepository.iterator();
while(itr.hasNext()) {
ResourceListObject iteratedImage = (ResourceListObject)itr.next();
if(iteratedImage.getName().equals(currentCheckBox.getText())){
boolean isAdded = imagesToBeImported.add(iteratedImage);
descriptionPanel.updateDescription("The image selected for importing is "+currentCheckBox.getText());
if(isAdded){
currentCheckBox.setForeground(Color.GRAY);
currentCheckBox.setToolTipText("This image is already on the list of images to be imported and can't be selected again.");
}
}
}
updateImagesToBeImportedPanel(panel_1, imagesToBeImported);
}
checkBoxNumber++;
}
So I want the user to think of it as drag and drop but in the backend I would be doing my own thing .
I'm very new to Java and am having some issues looping through JCheckBoxes on a UI. The idea is that I have a bunch of checkboxes (not in a group because more than one can be selected.) When I click a JButton, I want to build a string containing the text from each selected checkbox. The issue I'm having is that our instructor told us that the checkboxes need to be created via a method, which means (see code below) that there isn't a discrete instance name for each checkbox. If there were, I could say something like
if(checkBox1.isSelected()) {
myString.append(checkBox.getText());
}
That would repeat for checkBox2, checkBox3, and so on. But the method provided to us for adding checkboxes to a panel looks like this:
public class CheckBoxPanel extends JPanel {
private static final long serialVersionUID = 1L;
public CheckBoxPanel(String title, String... options) {
setBorder(BorderFactory.createTitledBorder(BorderFactory
.createEtchedBorder(), title));
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
// make one checkbox for each option
for (String option : options) {
JCheckBox b = new JCheckBox(option);
b.setActionCommand(option);
add(b);
}
}
}
This is called like this:
toppingPanel = new CheckBoxPanel("Each Topping $1.50", "Tomato", "Green Pepper",
"Black Olives", "Mushrooms", "Extra Cheese",
"Pepperoni", "Sausage");
So I now have a panel that contains a border with the title "Each Topping $1.50", and 7 visible checkboxes. What I need to do is get a list of all the selected toppings. We are not supposed to use an ActionListener for each checkbox, but rather get the list when a button is clicked. I'm feeling really clueless here, but I just can't figure out how to get the isSelected property of the checkboxes when the individual checkboxes don't have instance names.
Ideally I'd like to somehow add all the checkboxes to an array and loop through the array in the button's action listener to determine which ones are checked, but if I have to check each one individually I will. I just can't figure out how to refer to an individual checkbox when they've been created dynamically.
I'm assuming you're not allowed to alter the CheckBoxPanel code at all. Which seems like a useless exercise, because in the real world, you'd think that if CheckBoxPanel where a class being provided to you (e.g. in a library) it would include a way of getting the selected options. Anyway, due to the limitation, you could do something like this:
for( int i=0; i<checkBoxPanel.getComponentCount(); i++ ) {
JCheckBox checkBox = (JCheckBox)checkBoxPanel.getComponent( i );
if( checkBox.isSelected() ) {
String option = checkBox.getText();
// append text, etc
}
}
I suggest you maintain a list of checkboxes:
List<JCheckBox> checkboxes = new ArrayList<JCheckBox>();
and before add(b) do:
checkboxes.add(b);
You may then iterate through the list of checkboxes in the buttons action-code using a "for-each" loop construct:
for (JCheckBox cb : checkboxes)
if (cb.isSelected())
process(cb.getText()); // or whatever.
Alternatively, if you need to keep track of the specific index:
for (int i = 0; i < checkboxes.size(); i++)
if (checkboxes.get(i).isSelected())
....
I would suggest that you dont put each of the checkboxes in a List when you create them. Instead, in your shared ActionListener, you maintain a Set of all selected checkboxes. Use the getSource method on the ActionEvent to identify which checkbox the user selected and then cast it to a JCheckBox. If isSelected() returns true for the item in question, attempt to add it to your selectedItems Set. If it is not, then attempt to remove it.
You can then just iterate over the subset of all items (only those that are selected) and print them to the console.