I understand the "How to Use Actions" tutorial, but can't figure out how to make it work between multiple JFrame forms.
I tried making updateComboBox method public static so it could just be accessed from other forms,
but the NetBeans IDE refused to allow it since the auto-generated non-static variable jComboBox cannot be referenced from a static context.
The primary form contains a JComboBox that needs to be modified based on user input (menus, buttons, text fields, etc.).
Some of the widgets are on the primary form, others are on secondary forms.
For example, the primary form makes a secondary form visible; the secondary form makes some changes to the configuration; then the user hides the secondary form by pressing the SAVE button.
How can the secondary form best let the primary form know that the configuration has been updated and changes now need to be applied to the JComboBox?
Is an Action a good fit for this or would some other method be more appropriate?
public class Controller extends javax.swing.JFrame {
...
private javax.swing.JComboBox jComboBox;
private void updateComboBox() {
String[] names = Configuration.getNames();
for (String n : names) {
jComboBox.addItem(n);
}
...
How about a controller class which will hold references to your frames and manage the signaling you need? You can also take a look at the Observer pattern, where your primary form will listen the changes made by the secondary form.
Since the second form does some setting modifications, I would assume that while the user is messing around with the settings, you would like to disable the user from using the main application.
What you can do is to create the first form and then create the settings form from within the first form. You can then use thread synchronization (such as locks) to make the 1st form wait until the user has pressed the "OK Button" on the settings form. Once that the "OK button" is pressed, the lock is removed and the 1st form will continue executing by calling methods pertaining to the 2nd form so that it can access the data that the user has just entered.
Related
I defined a paste method in a controller class, based on the solution given here: How to copy/paste table cells in a TableView. Everything went well, except for one detail: some cells where data is pasted have events that should be triggered but are not.
For example:
public class MyController {
private TableColumn<MyBean, String> valueColumn;
...
valueColumn.setOnEditCommit(e -> doSomeStuff(e));
private void doSomeStuff(CellEditEvent<MyBean, String> event) {
...
}
In this example, after user hits ENTER, the doSomeStuff method is called, which is expected behavior.
The problem with the paste method I implemented is that it does not affect the cell, only its content (its ObservableValue). This means of course that after data is pasted, no event is triggered.
My question : is there a way to trigger the same event, or a similar one that will call my doSomeStuff method after pasting data?
Table View doesn't work as you think. If you want to have a fully customizable structure, use a grid pane. It is hard to create one, but after you make it look like a table, you have many more options to customize.
I did that I a recent project where I was needed to insert a table inside a cell. It was much more easier with a gridpane and textfields.
I have a form that contains a text field input that is bound to a field in a model object. When a user enters data into that text field it can affect multiple other fields/components within the form based on calculations. My business logic is encapsulated in a service layer.
Theoretically the way I want this to work is that when the user updates the field, an ajax call is made to the server (on keypress) where the logic from the service is applied and all affected fields are updated on the model object. Once the model has been updated on the server, I want to sync the current state of the model object to the screen.
Is the only way to do this to refresh the entire screen? Is there a way to re-render only the components bound to the fields in the model that have changed? Also, if I refresh the screen, the field that is being edited is updated as well, is there a way to exclude this?
I am interested in any best practices for this technique.
Thanks
I assume from your tags that you're using wicket. Wicket uses Behaviors for this purpose. In the following example you will update both DropDownChoices if the input of the TextField changed. You just need to add those controls to the AjaxRequestTarget. Models of both DropDownChoices will be reloaded and rerendered at the frontend. Also make sure to call setOutputMarkupId(true) on controls you want to update.
TextField<String> textField = new TextField<String>("input");
Component dropDownA = new DropDownChoice<>("dropA").setOutputMarkupId(true);
Component dropDownB = new DropDownChoice<>("dropB").setOutputMarkupId(true);
textField.add(new AjaxFormComponentUpdatingBehavior("change") {
private static final long serialVersionUID = 1478280524536023725L;
#Override
protected void onUpdate(AjaxRequestTarget target) {
target.add(dropDownA);
target.add(dropDownB);
}
});
With Ajax you can update any Component you want, just make sure it has markup id (Component.setOutputMarkupId(true)).
You need to use AjaxFormComponentUpdatingBehavior or AjaxFormChoiceComponentUpdatingBehavior and in its onUpdate() callback you have to update the models of the respective FormComponents and then you can use FormComponent.this.getForm().visitChildren(FormComponent.class, IVisit) to visit all FormComponents of the current Form and add to AjaxRequestTarget only the ones you have updated.
Update
Another good solution (even better!) is to use Wicket Event bus. In the Ajax behavior you could broadcast an event:
component.send(getForm(), Broadcast.BREADTH, new UIChangedEvent(target, newValue));
where UIChangedEvent is your own class/POJO that brings the new value of the updated component and the AjaxRequestTarget.
Then the other FormComponents could override #onEvent() and use the value to calculate their new value and use the target to update themselves or not, depending on the earlier calculation.
(A general Question)
I have an assignment in which I have to build a sudoku and I thought about the classes/logic to build it and thought I could use an advice.
I want to use a JFrame and build on it a JPanel with TextFields (the user is supposed to "solve" the sudoku).
I have a class called "DrawSudoku" which draws an empty board. I have to draw an empty board first, so the "user" can type numbers in it.
On that board I have to check some logic. So I have to access the textFields themselves.
So far that's all I've done. Now I am thinking about building another class with the "logic" behind the board.
But I've encountered a problem
How do I get the JTextFields that exists on the JPanel, from another class?
Can I have separate classes for the Drawing and Logic Behind it?
Thanks!
On that board I have to check some logic. So I have to access the textFields themselves.
Not necessarily
How do I get the JTextFields that exists on the JPanel, from another class?
How do you assess the state of any object from another object -- via an accessor or "getter" method.
Can I have separate classes for the Drawing and Logic Behind it?
Not only can you, you absolutely should.
If this were my project I would consider doing the following:
First and foremost, create a non-GUI Sudoku model class. This could include:
SudokuCellValue enum (name it what you want), an enum that can hold a value from 1 to 9 as well as possibly an EMPTY value (although you could use null to represent this)
SudokuCell objects, ones that have boolean editable, and holds a single value to the above enum.
SudokuGrid object, a 9 x 9 grid of SudokuCells.
A mechanism to hook listeners into the model so that they are notified of changes in state -- i.e., changes in the SudokuCellValue held by one or more SudokuCell objects. The View (the GUI) will be one of the major listeners to this model, and will change its display when the model's state changers.
I'd create a View class, meaning the GUI,
One that holds a reference to its model (see above)
and one that has attached listeners to its model -- I like to use PropertyChangeListeners for this
I'd hook it up with a grid of JTextFields,
These text fields would use a DocumentFilter to allow the user to either clear the field or enter only 1 through 9 single digit numeric text.
Would be enabled for input (or perhaps better -- focusable for input), based on the editable state of the corresponding model cell.
I'd create a Controller that would control some of the communication between the view and model.
With this type of set up, outside classes could listen for changes to the model and wouldn't have to have any access directly to the JTextFields of the view.
You don't need to have access to the text fields themselves if you include public methods in your DrawSudoku class that your logic class can then call. This would be very similar to writing getter and setter methods for private variables. For example, if you wanted your logic class to be able to write the number "6" into a certain square on the board, you could write a method in DrawSudoku like this:
public void setSquareText(String text, int row, int column) {
// change the appropriate text field here
textField.setText(text);
}
Then, call this method in your logic class, by making an instance of the drawing class:
DrawSudoku drawer = new DrawSudoku();
drawer.setSquareText("6", 1,1);
Alternatively, you could write a method in DrawSudoku that returns a given JTextField, like this:
public JTextField getTextField(int row, int column){
// find the appropriate text field, then return it
return textField;
}
Then, call this method in your logic class to get access to the JTextField, like this:
JTextField textField = drawer.getTextField(1,1);
textField.getText();
textField.setText("6");
I'm trying to create a my own way of selecting because I want to select across multiple edittexts. And selection might include other Views also (not just text).
I have so far found that the android.text.Selection class handles text selecting. As this class is a static (constructor private) class it ensures that in the application there is no way to create 2 or more selections simultaneously (because when you add a new selection,it has to be done through this class and this class removes the previous selection when adding a new one). Therefore there is no way to select text in multiple edittexts at the same time.
So I'm trying to create my own way of selecting (yes, manually add a backgroundColorSpan when user does what is done when selecting).
But how do I deal with the anchors? As android is open source I'd like it if I can find the class that handles selection anchors (in other words the class which determines when to call Selection class to extend selections to the next line based on how user drags the anchor.) So in which class does this happen exactly?
For anyone interested it's the,
android.widget.Editor class
I am having trouble understanding the undo/redo functions using UndoManager, and integrating it with the MVC model.
I am not sure where to put the various methods(in model, view or control)
and I am still not sure how to use the undo manager.
My control class implements UndoableEditListener
It creates:
private UndoManager manager = new UndoManager();
and in:
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("Undo")) {
try {
manager.undo();
} catch (CannotUndoException ex) {
ex.printStackTrace();
}
}
}
I understand up to here, but the rest I am not sure what to do. I know I will have to add more in the model and view class, but not sure where.
DO I have to have the following classes?
public class UndoAction extends AbstractAction {}
public void undoableEditHappened(UndoableEditEvent e) {
I am simply placing an integer number in a textfield, and then I want to be able to undo this.I set the number in the textfield in the view class.I want to acheive this the simplest way possible, no fancy coding! This is a minor part of my assg but I just cant get it working!!
==========================================================
Here is a more detailed description of my code, maybe it will help:
I have a model, view and control package.
Contol has:
ButtonGUIControl.java, which implements both
ActionListener and
UndoableEditListener.
final UndoManager manager = new UndoManager();
In the actionPerformed method, it calls
if (e.getActionCommand().equals("Undo")){
try {
manager.undo();
}
and in:
public void undoableEditHappened(UndoableEditEvent evt) {
manager.addEdit(evt.getEdit());
}
In the View:
Grid.java , which extends JTextField will add the following, wherever it needs to display a number on the GUI:(model is simply an instance of my Model class)
getDocument().addUndoableEditListener(new ButtonGUIControl(model));
Could it be because the UndoManager is being created in a different package? I really have no idea how to debug this anymore!!
I could post my entire code if that helps. I guess Im not sure how to integrate this with my mvc model structure.
Take a step back for a second. The whole idea here is that a user will use your app and will make a series of changes to something. A text editor is a good example. You can insert characters and lines, delete them again, replace text with other text, scroll the text, etc. In order to support this with MVC you have a model that holds state and a View that displays it.
Your first instinct might be to have the view directly access the model, and then refresh the view every time the user makes a change, but it's very hard to undo those changes with that implementation. Instead, you encode every kind of change the user can make in classes that are able to perform that change and can later undo that change.
For example, an action that inserts text would be implemented by a class that knows the character offset of the insertion point and the string of characters that is to be inserted. The perform action would insert the string at the offset and the undo action would remove the right number of characters after that insertion point. You'd have a different class that would handle deletion, another to handle scrolling etc.
Every time the user takes some action, the view would construct one of these UndoableEdit classes and would tell the instance to run itself (redo()). Once executed, you put that UndoableEdit at the end of a list of UndoableEdit instances that represent all of the actions the user has taken so far. This list makes it very easy to support any sequence of undo requests, redo requests and actual edit actions (resulting in more UndoableEdit's being put on the list).
So back to your question. If your app needs to support undo and redo, then you'll need to implement an UndoManager which simply manages the list of UndoableEdit's and performs undo and redo as necessary. You also have to implement a whole bunch of UndoableEdits, one for each kind of thing your user will do against the UI. As for a listener, I can't see that you really need to do that one.
If you need only simple undo/redo, you can use UndoManager as it is, you don't need to subclass or customize it in any way.
JTextField (more specifically its model, the Document) has some built-in support for undo, which means you don't need to write UndoableEdit implementations either, the UndoableEdit objects will be automagically created for you (actually AbstractDocument.DefaultDocumentEvent implements UndoableEdit).
Full simple working example is here