Making a cell visible in JTable when AbstractTableModel is extended - java

I have extended the AbstractTableModel to suit my requirements. Now this table can be altered by other methods of my GUI. I want the table to scroll to the currently edited cell into view. To do this, I think I have to first get the JViewport of the current JComponent, but I see no method by which I can achieve this? How do I achieve this?
I have already done this when I have used the default JTable, but how do I do this when we extend AbstractTableModel?

Models are designed to store data and notify views when the data has changed. It notifies the view of a change in data by firing events. It is the responsibility of the view to listen for these events. Therefore the model never knows directly what view is being updated. This type of functionality should NOT be part of the model.
One approach might be to use a TableModelListener. You can create a TableModelListner with the table as a paramenter. Then when data is changed the listener will be notified. You can then invoke table.scrollRectToVisible(...) on the table. However, with this approach you can't distinquish between edits that have been applied directly through the TableModel versus udates that have been done through the JTable itself.

You may want to have your table fire an event, and have your parent component listen for that event, and scroll accordingly. That way your table doesn't need to know about its parent scroll pane.
You can make use of the EventListenerList in DefaultTableModel to notify any listeners.

Related

How do CellEditors work?

I have problems in understanding how CellEditors work in Java.
I have a JTable with a model (extends AbstractTableModel).
The JTable has its CellRenderer and CellEditor.
The CellEditor only overrides
isCellEditable()
(one condition added).
How do the changes I made in one Cell go to the Model?
Does the Model has to implement an CellEditorListener and react on
stopEditing()?
I have read, that the changes would automatically be stored in the model.
Is that true? If yes, how does it work? Do I have to react on
tableChanged()
then?
Please explain the way of the data, which have changed and at which steps I have to do something.
Thanks a lot!
The changes are applied to the model via the TableModel's .setValueAt() method. The JTable itself takes care of receiving the value returned by the CellEditor and passing it to the TableModel.

UndoRedo.Manager and JCheckBox

I am using the UndoRedo.Manager to implement Undo/Redo functionality in a Netbeans RCP application. The undoableEditListener can be added to any Document, that limits its use to text-related fields. Does anyone know how i can add such a listener to elements without a Document, like a JCheckBox?
Just create custom CompoundEdits or even separate edits. See for example the edits merging in one http://java-sl.com/tip_merge_undo_edits.html
I think all you need is to keep own events stack and implement custom UndoableEdits which don't change model (Document) but change state. In other words you need more complicated model to keep checkbox state as well as Document in one. All the complicated model changes (state change or docuemnt change) should be represented by custom UndoableEdit class. The class instance could be wrapper for Docuemnt edit event or just custom event.

JTree selection without generating event

I have a JTree, a JTable and a JList which displays the same set of objects, but in different order and with different information. If an item is selected from one of the Component, I want to select the same object on the other two Components (meaning they should be highlighted). Naturally I monitor the selection events with a Listener. Here is the problem, when a Component retrieves the selected object, I'll have to make sure the object is selected on the other Components by calling selection methods on them. This, will then notify the selection listeners on the other two components. But each of those events will in turn call selection events on components other than itself, causing an infinite loop going among the three Components.
I see one solution is to use a boolean flag, and make the listeners not propagate the selection if the flag is set. However, this seems cumbersome and not elegant. Is there a way to simply tell JTree, JTable and JList to make the selection but not fire any events (as oppose to fire an event and then catching and stopping it with a boolean flag)?
Take a look at SharedModelDemo. I think it does what you're looking for.
I would use a flag indicating whether it's user changes or internal changes but yu can also remove listeners before selection call and add them after to prevent events firing.

Issue updating a parent JFrame

First, let it be known that I'm new to java and it's quirks. I'm a seasoned programmer with various languages, which may be why I'm stuck...
I have an application that, possibly due to poor design, spawns new JFrames through the users' work-flow. My question is, if there is an event in a spawned JFrame, is it able to contact and pass data or an event to it's parent?
I have read that using a JDialog seems to be the way to design, but let's assume that's not an option. Essentially, JFrame1 contains a JTable with a list of data. An action spawns JFrame2 and a user "does something" that impacts the data in the list in JFrame1. Upon closing JFrame2, is there a way to control the JTable based on JFrame2's close event?
It's a pretty basic concept, I just can't seem to find the mechanism that would allow such an action.
Thanks!
You can use "listeners" to listen for various events.
It sounds like you might want to start with How to Write a Window Listener.
I have read that using a JDialog seems to be the way to design, but let's assume that's not an option.
Why? The code is the same and JDialogs where designed for this purpose. What is the specific requirement that says you need to use a JFrame?
An action spawns JFrame2 and a user "does something" that impacts the data in the list in JFrame1. Upon closing JFrame2, is there a way to control the JTable based on JFrame2's close event?
This is a common design. The user selects a row to change or update and a model dialog is created to display all the data so it can be changed. When the dialog is saved the data in the table is updated. If this is your requirement, then you can just pass in the TableModel to the dialog. Then when the dialog is closed you update the TableModel and the table will be repainted automatically.
You would have to capture the window closing event using a window listener. The window listener would also need a reference to the data that needs to be changed.
In addition to using Window.addWindowListener() on either a JFrame or a JDialog, consider using a model-view approach. Have the close event modify the table's data, rather than the table itself. Use AbstractTableModel as the model for the table, and listen for changes to the data.

Design for TreeCellRenderer

I have been looking into JTree and TreeCellRenderer. It seems in general, the application (with one JTree) has only one instance of TreeCellRenderer. The application makes multiple calls to TreeCellRenderer's getTreeCellRendererComponent method to decide how each TreeCell is drawn, and such call are made in many occasions (when a cell is selected, deselected, move over, when scrolling, etc.). Why did they decide to do that instead of having multiple instances of TreeCellRenderer, each responsible for one cell??
I am trying to make a JTree where each cell contains a checkbox. The checkbox can be checked/unchecked by the user. Then, the TreeNode userObject's values are set base on the state of these checkboxes. But, from the current JTree design this is impossible - since there is only one instance of JCheckBox, and is only used to show how the Cell looks like (you can't really check it). In some sense I want to separate selection of the TreeCell and the checking of the boxes.
I have some workarounds (implementing MouseAdapter and checking if the mouse click is close by where the checkbox is rendered, then emulate a check on the box by changing its appearence in TreeCellRenderer), but still I want to know if this can be done more directly. Thanks!
Why did they decide to do that instead of having multiple instances of TreeCellRenderer, each responsible for one cell?
This is a nice example of the flyweight pattern.
For a check box tree, I like org.netbeans.swing.outline.Outline, mentioned here, but other examples are available.
Addendum: Reading your question more closely, you ask:
In some sense I want to separate selection of the TreeCell and the checking of the boxes.
This is the correct instinct: The data (checked or unchecked) should be stored in the model (TreeModel), not the view (JCheckBox). The example uses instances of CheckBoxNode in it's (implicit) model, accordingly.

Categories