I've problem regarding GUI with one Menu and one Order Class.
I've created a variable to store how many items have been selected in the Menu Class.
private int totalSelected;
The var totalSelected is live updated. It can be changed anytime depending on actionPerformed() function.(Exp: totalSelected will add up all the selected items)
In the Order Class, how can I access to the live update variable totalSelected in order to retrieve the live update value? When I invoke getTotalSelected() function inside the Menu Class, I will only obtain a 0 value.
Thanks for your help ^^!
Please allow me to specify my question clearer.
public class MenuTab extends JPanel
{
private JLabel display;
private int totalSelected;
public MenuTab()
{
....
}
}
public getTotalSelected(){
return totalSelected;
}
private class SelectedListener implements ActionListener
{
public void actionPerformed()
{
.......
//Assume that totalSelected has been updated!
display = new JLabel("Total: " + totalSelected);
// OK to display totalSelected live value here.
}
}
// A new class is the confirmation of order
public class OrderConfirmedTab extends JPanel{
private JLabel displayTotal;
private MenuTab order = new MenuTab();
public OrderConfirmedTab()
{
......
int totalSelected = order.getTotalSelected();
displayTotal = new JLabel("Total: " + totalSelected);
// Problem to display totalSelected live value here.
// Will obtain 0;
// How can I obtain the live updated value from class MenuTab? Thanks!
}
}
If I read your code right, you need to make your variable be private static int totalSelected; You need to make it static so that it stays the same for all instances of the class.
I looks like your not updating the private int totalSelected; variable when a user makes a selection, so it is always 0.
Ya! I just realized that my JLabel
will not update the value
automatically. So how can I fix it?
Thanks! – Christine
If I understand you correctly you have two GUIs where changes in one (the MenuTab) will update the other (OrderConfirmedTab) in real time?
If so, you will need to increase the coupling between the two objects. If MenuTab has a reference back to OrderConfirmedTab then it can call methods to update the value as it changes.
For example, pass OrderConfirmedTab into MenuTabs constructor
MenuTab mt = new MenuTab(this); // from within OrderConfirmTabs costructor
Then when MenuTab has an actionPerformed event it can call back to OrderConfirmTab
orderConfirmTab.setTotalSelected(totalSelected); // you have to create this method in OrderConfirmTab
I hope this helps a little
You can use PropertyChangeListener and PropertyChangeSupport mechanisms to dispatch an event when the value is updated and to be notified when the variable has changed. Your JLabel is not going to update on its own; even if you were to use an object other than a primitive (note that primitives are merely values, while objects are actually implicit pointers); you will need to update your JLabel when the variable changes, since the JLabel simply stores a string, not a reference to the variables from which the string was constructed.
This is the concept of model-view-controller; your variable should be in some sort of class or classes that represent the model (the information) and which allow changes to be observed via property change events. Your view classes should simply provide display logic and no business or application-specific logic. It is the controller in which your application logic should reside; your controller should register for events on the model, and it should update the view whenever the model has changed, and it should likewise update the model when the view dispatches events that should result in the model being changed.
Related
I use Vaadin 14 and would know whether it is possible to report changes in the nested list to objects in the main view.
A rough example is shown in the picture. Above you can see the sum as size (here 2), if I press Delete it should change to 1.
Is that possible and how?
concept
I don't have any code yet, it's a thought where I would like to have a hint about what would be possible, e.g. Observer Pattern or something, but code could look something like this
code:
#Rout("")
public class MainView extends VerticalLayout {
private List<CustomDetails> customDetails = new ArrayList<>();
public MainView(){
final var form = new FormLayout();
customDetails.forEach(form::add);
add(H1("Header"), form)
}
}
public class CustomDetails extends Details{
private CustomForm customForm;
private final Service service;
public CustomDetails(){
customForms = new CustomForm(service.getListOfObjects());
this.setContent(customForms)
}
}
public class CustomForm extend FormLayout{
private FormLayout formLayout = new FormLayout();
private List<Object> objects = new LinkedList<>();
public CustomForm(List<Object> list){
this.objects = list;
setUp();
add(new Paragraph("SUM: "+ list.size()), layout);
}
private void setUp(){
objects.forEarch(o->{
....
layout.add(...)
})
}
}
In Vaadin there is an utility class Binder which is used to bind data to forms. If your use case is related to this, i.e. your so called nested layout is in fact a form and objects you refer to are data beans you want bind into that form. I recommend to study that first.
If you have list editor, I would also investigate if it fits your application to implement it with Grid or IronList/VirtualList, which is backed by DataProvider. Say you edit one item, and after saving the item, you can call dataProvider.refreshItem(item) to update the view.
Observer Pattern or something...
Yes, that is a solution. It is a lot of work and has been done before.
One such library is Beanbag.
Note: I wrote this (or rather, I started writing it a day ago).
EDIT:
As of this edit, we have the ObservableCollection interface. You can use it like so:
// You have a collection called "strings".
// Wrap it in an ObservableCollection.
final ObservableCollection<String, Collection<String>, BasicObservableCollection.Default<String, Collection<String>>> observableStrings = ObservableCollections.observableCollection(strings);
// Add a removed observer.
observableStrings.addElementRemovedObserver(observation -> System.out.println("\"" + observation.getValue() + "\" was removed.");
// Remove an element.
observableStrings.remove("hello");
If you need the wrapper to have List methods, just wait until tomorrow evening EST. I'll have the code up by then and will update this post accordingly.
I have created a class which extends JavaFX's MenuBar that creates a menu bar for my application.
By default I won't specialized operations, like opening/saving a file and running a simulation, to be disabled (and they are). When a user runs the app they can select an item in the menu File>New>, and based on which component they select it will toggle on the appropriate menu options.
I was planning on doing this by having each component give a list of which items it toggles on, and then activating the appropriate items when the component is created.
However, I cannot access the list of menus from within in a function (am trying to do it with this.getMenus() but from within the function the only function that is recognized it this.getClass()).
Does anyone know why I cannot call getMenus() and how I could get access to it?
Alternatively, if you have a better idea for how I can toggle these menu items, I'd love to hear. I don't think this is a good way to do it, but it is the best idea we have come up with.
private void fileNew()
{
Menu fileNew = new Menu("New");
menuFile.getItems().add(fileNew);
for(String k: CLHM.keySet())
{
CComponent comp = CLHM.get(k);
if(comp.supportedFeatures().contains((new SupportsNew())))
{
MenuItem i = new MenuItem(comp.getName());
fileNew.getItems().add(i);
i.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent event)
{
CComponent ctemp = CLHM.get(i.getText());
ArrayList<String> menuItems = (ArrayList) ctemp.getMenuItems();
for (String s : menuItems)
{
Scanner scanner = new Scanner(s).useDelimiter("\\s>\\s");
String menu = scanner.next();
//Menu temp = this.getMenus();
/*
Here the program will parse the string of the
Menu path (e.g. File>Open) and activate the
relevant item, if it exists.
*/
}
borderPane.setCenter((Node) ctemp);
}
});
}
}
}
When you use this inside an anonymous class, it actually refers to the anonymous class instance. So in your case, this is an instance of EventHandler, which is why there are so little methods that you can call (because it is an interface type).
What you are looking for is YourExtendedMenuBar.this.getMenus(). This will tell the compiler that you are looking for the enclosing instance. Alternatively, you can simply drop the this keyword (i.e. getMenus()). Doing so will allow you to use/call any accessible members of the anonymous class and its enclosing class.
On the side note, if you replaced that anonymous class with a lambda expression, then this would have meant YourExtendedMenuBar. It is not possible to access any members of the class that the lambda expression represents, at least not directly.
P.S. I have no idea what your toggling is all about, so I can't answer until I figured out what you mean.
I have a quick question. I don't get it...
I've got a JFrame where I add a JComboBox:
JComboBox<String> Team_ComboBox = new JComboBox<>();
Team_ComboBox_Handler ComboBox_Listener = new Team_ComboBox_Handler();
Team_ComboBox.addActionListener(ComboBox_Listener);
Team_ComboBox.addItem("Test 1");
Team_ComboBox.addItem("Test 2");
On this Frame I have a button which opens another JFrame.
Play = new JButton();
Play.setText("Play");
Play.setPreferredSize(dimension);
Play.addActionListener(menuhandler);
private class main_menuhandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==Play){
teams Team = new teams();
Team.teams();
disposeMainMenue();
}
if(e.getSource()==Close) {
System.exit(DO_NOTHING_ON_CLOSE);
}
}
}
Anyway, I would like to transfer the Selected value of the Combobox to a method of the other class. I know how I can get the itemvalue of the combobox in the method itself (with getselecteditem) But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method.... I created another ActionListener (comboBox_Listener) but I haven't put any code into it...
Any idea? Thanks a lot in advance
Several issues appear to me:
Your main question:
But how can I do that in the ActionPerformed Method as I can't access the combobox in the ActionPerformed method
Your likely best solution is to change your code and variable declaration placement so that you can access the JComboBox fromt he actionPerformed method. If you're declaring the combobox from within a method or constructor, change this so that it is a proper instance field of the class.
Other problems:
You should not be creating multiple JFrames. If you need a dependent window, then one should be a JDialog. If not, then consider swapping views with a CardLayout.
Learn and follow Java naming conventnions so others can better understand your code. Class names begin with capital letters and methods and variable names don't for instance.
I am not sure why you're doing this: System.exit(DO_NOTHING_ON_CLOSE);. Why pass that constant into the exit method?
Use a constructor for your action listener class:
private class main_menuhandler implements ActionListener {
private JComboBox<String> Team_ComboBox;
public main_menuhandler(JComboBox<String> Team_ComboBox){
this.Team_ComboBox = Team_ComboBox;
}
}
Now you can create the class main_menuhandlervia the constructor and add the combobox to it.
In your Overriden action you have access to it.
Try playing around with this as your code snippet isn't broad enough to actually provide proper code. But this should answer your question
I have many .java files within my project. From FTall.java i want to access {text field} t1 ('main' jFrame -> jPanel2) of the FormTTS.java
I am right now getting errors due to that only, because it cannot find symbol t1.
It is private and i cant change it to public
Edit:
I am using this code already to open up FTall from the FormTTS.java:
In a button in FormTTS
FTall forma = new FTall();
JFrame frame = forma.getFrame();
forma.setVisible(true);
and this in FTall
public JFrame getFrame() {
return jFrame1;
}
Because of the way your code is structure, you need to supply some way for FormTTS.t1
In FormTTS, provide a method to exposes t1, something like getMainTextField for example...
public JTextField getMainTextField() {
return t1;
}
You're next problem is FTall is going to need a reference to an instance of FormTTS. Probably the easiest way would be to pass a reference to the constructor of FTall
private FormTTS mainForm;
public FTall(FormTTS mainForm) {
this.mainForm= mainForm;
}
This will allow you to access t1 by simply using the mainForm reference...
JTextField field = mainForm.getMainTextField();
Personally, I would prefer not to expose the text field as it gives too much access to callers, instead I'd prefer to return the text and if required provide a means to change it...
So in FormTTS, I might do something like...
public String getMainText() {
return t1.getText();
}
// Do this only if you need to have write access
public void setMainText(String text) {
t1.setText(text);
}
But that's just me...
To obtain the value, you would use a similar approach as above (to getting the text field)
String text = mainForm.getMainText();
if i am understanding your question its simple first ensure that your text field come in to scope before access and once it come in, then use a setter to set its refrence in required class then you can access it.
I am trying to setup a button similar to the save button with the default CRUD database template (where the button only becomes active if a variable is true). I have looked at the code for the save button and worked out that i need:
A variable to link it with (saveNeeded in their case)
An action to run
I have recreated both of these on another button but it never seams to get enabled. I have print statements on 2 other buttons i am using to set the variable i have my button linked to to true and false so i can see the value is changing.
Is there some crucial step i am missing? this seems like it should be fairly straight forward.
One other thing, if i manualy change the variable to true in my constructor to true and run the application it enables the button and false disables it so that part is working, just not the change.
Any help would be appreciated as i have spent the last few hours trying and can not figure it out
Thanks
The variable or "property" needs to be watched somehow, perhaps by using a PropertyChangeSupport object and allowing other objects to add a PropertyChangeListener to it, making it a "bound property". There's a special version of this for Swing applications that takes care with the Swing event thread, SwingPropertyChangeSupport, and you may wish to use it.
Edit
You asked
Thanks for the reply, i assume that would be what firePropertyChange("saveNeeded", !saveNeeded, saveNeeded); is doing but waht is this doing? does this just notify the program or do i need to catch an handle this somewhere. This is based off the pre generated code so im not sure if it added something in the background.
The class that holds the watched variable would need a private SwingPropertyChangeSupport field. You would give it a public addPropertyChangeListener method where you'd allow other classes to listen to its bound properties, something like this (if the property were a String):
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
public class Foo {
public static final String MY_BOUND_PROPERTY = "My Bound Property";
private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
this);
private String myBoundProperty;
public void addPropertyChangeListener(PropertyChangeListener listener) {
spcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
spcSupport.removePropertyChangeListener(listener);
}
public String getMyBoundProperty() {
return myBoundProperty;
}
public void setMyBoundProperty(String myBoundProperty) {
Object oldValue = this.myBoundProperty;
Object newValue = myBoundProperty;
this.myBoundProperty = myBoundProperty;
PropertyChangeEvent pcEvent = new PropertyChangeEvent(this,
MY_BOUND_PROPERTY, oldValue, newValue);
spcSupport.firePropertyChange(pcEvent);
}
}
Then any class that would like to listen for changes would simply add a PropertyChangeListener to an object of this class and respond to changes as it saw fit.