GWT Spreadsheet Cell - java

I am trying to reproduce the behavior of a spreadsheet cell using GWT. I was able to make a Composite widget called "Cell" which is by default a "Label" widget. When a user clicks on this widget, it becomes a "TextBox" widget. On a blur event, the widget becomes a "Label" widget once again.
My question concerns efficiency and rendering time. It would probably be easiest to just make my "Cell" a "TextBox" and just change the appearance to the user via CSS (according to whether they are entering data or not). However, I think that this will affect rendering time and so I revert to a "Label" widget whenever input is not necessary. The problem with this method, however, is that I am basically creating a new TextBox/Label each time the user needs to enter anything into the "Cell".
Here is my pseudo-code (since I am not around an IDE)...
public class Cell extends Composite {
private SimplePanel sp;
public Cell() {
Label l = new Label("");
sp.add(l);
}
private void switchMode() {
Widget w = sp.getWidget();
if (w instanceof Label) {
// we have a Label, change it to a TextBox
String text = ((Label) w).getText();
sp.remove(w);
sp.add(new TextBox(text));
// force garbage collection
w = null;
} else {
// we have a TextBox, change it to a Label
String text = ((TextBox) w).getText();
sp.remove(w);
sp.add(new Label(text));
// force garbage collection
w = null;
}
}
...
When there is a onBlurEvent on the TextBox or when there is an onClick event on the Label, the switchMode() method is called. Critiquing of code is welcomed.
Would it instead be smarter to include a TextBox and Label as private variables of the Cell class, and then just add or remove the corresponding object as needed?

We met similar problem: efficient display of excel-like table (a lot of rows and cols, each cell in-place editable).
The final solution was: render the table as string: each cell is rendered just as text, put all via innerHTML.
When the user selects a cell with mouse or keyboard, special hidden TextArea appeared over the selected cell (with the same size) and focus gives to the TextArea. OnBlur - text entered goes back to the cell and the TextArea is hidden again.
We use no widgets for cells. The TextArea is only one for the whole table.
See also
"Effective GWT: Developing a complex, high-performance app with Google Web Toolkit"
http://code.google.com/events/io/2009/sessions/EffectiveGwt.html

An even easier way would be to have both of them added to your panel (not simplePanel though), and use setVisable methods to alter visability.

Related

editing a cell in a JTable seems to alter the behavior of the table after a Tab button is pressed

I have a JTable and I intend to add a row each time the Tab button is pressed whilst the cell that corresponds to the last row and the last column has focus. The code on Netbeans is as follows
private void tblReplenishKeyPressed(java.awt.event.KeyEvent evt) {
if(evt.getKeyCode()==KeyEvent.VK_TAB ){
int rows = tblReplenish.getRowCount()-1;
int columns = tblReplenish.getColumnCount()-1;
if(tblReplenish.getSelectedRow()==rows && tblReplenish.getSelectedColumn()==columns){
model.addRow(new Object[]{});
}
if(tblReplenish.getSelectedColumn()==0){
String code = model.getValueAt(tblReplenish.getSelectedRow(), 0).toString();
model.setValueAt(supplier.get(code), tblReplenish.getSelectedRow(), 1);
}
}
}
The only problem is that if the Tab button is pressed soon after editing whilst the cursor is still blinking inside the last cell at the bottom, no row is added but focus is given to the cell that corresponds to row 1 and column 1. Any help will be appreciated as I am new to java
The problem is you added the KeyListener to the table, but focus in on the text field when you edit a cell so your listener code is not invoked. You should NOT be using a KeyListener
All Swing components use Key Bindings to bind a KeyStroke to an Action. So you need to replace the default Tab Action with a custom Action of your own.
You can also check out Table Tabbing which provides a simple API that allows you to use the default Tab Action and add some custom code.

Creating a JComboBox in a JTable with the dropdown always visible

In Swing is possible to create a JComboBox in a JTable, as seen by this guide from Oracle. They have a lovely picture that shows this in action:
However, what the fail to show is that if you haven't clicked on the cell, the dropdown arrows are not visible and it just looks like a normal text label, as seen below:
You can see that knitting has dropdown arrows because I just clicked on it, but the other ones don't. This is sadly less than ideal because there are no visual cues that the cell can be clicked on to show a list of options. In other words, the "Sport" column looks identical to the "Last Name" column. One of them is a dropdown, the other is not, but they visually look the same unless you happen to click on one of them.
Is there any way that this can be done in Swing?
EDIT: To clarify, what I want is for ALL the cells in the "Sport" column to have arrows indicating a dropdown menu, even if they were not the least one clicked. Basically, I want it to look like a combo box whether I've clicked on it or not.
I'm not sure you understand the distintion between "renderer" and "edit" modes in the JTable. All the cells in the Sport column in your example are backed by a combobox, when in edit mode.
What I believe you're trying to do is something like...
Which will clutter the UI (IMHO)
So based on the example from here, I modified the code to change the default cell renderer for the Sport column
public void setUpSportColumn(JTable table,
TableColumn sportColumn) {
//Set up the editor for the sport cells.
JComboBox comboBox = new JComboBox();
DefaultComboBoxModel model = new DefaultComboBoxModel();
model.addElement("Snowboarding");
model.addElement("Rowing");
model.addElement("Knitting");
model.addElement("Speed reading");
model.addElement("Pool");
model.addElement("None of the above");
comboBox.setModel(model);
sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
model = new DefaultComboBoxModel();
model.addElement("Snowboarding");
model.addElement("Rowing");
model.addElement("Knitting");
model.addElement("Speed reading");
model.addElement("Pool");
model.addElement("None of the above");
//Set up tool tips for the sport cells.
ComboBoxTableCellRenderer renderer
= new ComboBoxTableCellRenderer();
renderer.setModel(model);
sportColumn.setCellRenderer(renderer);
}
And added this...
public class ComboBoxTableCellRenderer extends JComboBox implements TableCellRenderer {
#Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setSelectedItem(value);
return this;
}
}
First of all, you may want to check this out: how to add checkbox and combobox in table cell?
In your example, I am thinking that this may be due to the fact that there is not enough height to display the GUI. What I mean is that the Swing components automatically resize to fill their container, and if the container height is too small, then it may not display the GUI correctly.
Here are images to illustrate my example (I used Windows XP):
Initial Launch:
Click on Cell:
After Cell Click:

Java: Show HAND cursor and change font of part of text in JTable row

I have a JTable with one column displaying certain text in every row
Like,
Example (www.example.com)
Test (www.Test.com)
Now, when mouse hovers on url i.e. text inside bracket cursor should change to HAND cursor and text inside bracket should be in different color and underlined to show that it looks like its an hyperlink
Tried lot of things but couldn't achieve.
Tried TableCellRenderer, but its changes the whole row content
Tried Map map =
new Hashtable();
map.put(TextAttribute.KERNING,
TextAttribute.KERNING_ON);
font = font.deriveFont(map);
but again it changes the content of whole row
Any solution would be great help
Object rows[][]={ };
Object headers[]={""};
TableModel model=new DefaultTableModel(rows,header);
String name= "Example";
String url="www.example.com";
String display = name + "(" + url +")" ;
(DefaultTableModel)model).addRow(new Object[]{display});
JTable table=Jtable(model);
Implementing a TableCellRenderer is the way to go. getTableCellRendererComponent can return any Swing component. So your question boils down to "how to show a string with multiple formats" and "how to change the cursor".
To show a string with multiple formats, you can use html in a single JLabel, use multiple JLabels in a JPanel or use a JEditorPane.
Setting a Handcursor boils down to a call to setCursor, which is available on all JComponents.
You can try
this.
And for adding multicoloured look for cell value in table use Label.
Have look over this
answer.

2 column jcombobox

I had quite a lot use for a multicolumn jcombobox, but have not yet found any nor managed to make my own. I have tried several approaches found in web, but they have not worked. Afterwards I read somewhere that those (old) does not work under current Java version.
I have managed to make my own so far, that the combobox has a table as dropdown list and I can select an item with mouse, but the goal is that when the user starts to type into the edit box, drop down list opens and cursor moves based on the text the user has written. It seems that the events from e.g. JTextField editor = (JTextField) comboBox.getEditor().getEditorComponent() does not work.
Has anybody managed to make a two column combobox or have any ideas, how I could get the event when the user starts to type.
You are looking for autocomplete functionality (as I understand the question): it's supported in SwingX - and quite easy to use.
It boils down to implemneting a custom ObjectToStringConverter and configure the comboBox with an autoCompleteDecorator using that converter. Something like:
/**
* A converter which expects an item of an array type and returns
* a string representation of its first value.
*/
public static class ArrayToStringConverter extends ObjectToStringConverter {
#Override
public String getPreferredStringForItem(Object item) {
if (!(item instanceof Object[])) return DEFAULT_IMPLEMENTATION.getPreferredStringForItem(item);
Object[] array = (Object[]) item;
return DEFAULT_IMPLEMENTATION.getPreferredStringForItem(array[0]);
}
}
// usage
// assuming an model with items being arrays
JComboBox combo = new JComboBox(arrayModel);
// the renderer supporting multiple columns, f.i. a table
combo.setCellRenderer(new TabularListRenderer());
AutoCompleteDecorator.decorate(combo, new ArrayToStringConverter());
A complete working example (including the renderer and showing how-to force the width of the popup to be larger than the combo itself) is TableAsListRenderer in my incubator section
BTW: the autocomplete functionality is a standalone module, accessible via maven or manually downloadable from the maven rep at java.net, you would want the swingx-autocomplete-1.6.4.jar (plus the corresponding doc/sources, if interested)
Has anybody managed to make a two column combobox or have any ideas, how I could get the event when the user starts to type.
you can to put JTable to the JComboBox, but by default you can to select only value from entire JTables row, not directly from JTables Cell (required additional workaround, not tried yet)
i still searching for this answer too
here's i try so far..
i create Jpopup and put the Jtable in there..
then i use jlabel not jcombobox,
when user click jlabel, then the popup(Jtable) will show in that jlabel location..
when user select value on jtable,
then the popup will dispose,
then the jlabel will show the result..
for your case, you can use jtextfield not jlabel
EDIT :
heres related question
enter link description here

How do I resize the dropdown of a combobox?

Background:
I am doing some UI work in an eclipse environment where I fill a combo control with some values. The string values have an different length and often a length greater than the combo width and the width of the parent composite.
Problem:
When I open the dropdown list, the width of the list is greater than the width of the parent composite and the user could not see the complete value of the list entry.
I have tried to use the "setTextLimit" option, but without success. For me it is perfectly adequate if I could set the width of the dropdon list with a constant value.
Code example:
this.mComponentName = new Combo (lComponentComposite, SWT.BORDER);
this.mComponentName.setTextLimit(COMBO_TEXT_LIMIT);
GridData componentNameGridData = new GridData();
componentNameGridData.widthHint = 166;
this.mComponentName.setLayoutData(componentNameGridData);
this.mComponentName.addSelectionListener(this.mComboSelectionAdapter);
this.mComponentName.addKeyListener(this.mComboKeyAdapter);
Greetings
dirk
While creating a combobox specify Horizontal scroll also
this.mComponentName = new Combo (lComponentComposite, SWT.BORDER|SWT.H_SCROLL);
This will not let the text overflow
That is really a good question. After digging through developer forums and even the source code, I lean towards saying it is not possible.
I solved the problem temporarily by switching to a CCombo, but I do not like the solution as I believe one of SWT's strength is in using native widgets, and the CCombo does not look as good (at least on Win7 and OS X).
When you select a drop-down combo box or drop-down list box to size it, only the right and left sizing handles are active. Use these handles to set the width of the box as it is displayed initially.
Choose the drop-down arrow at the right of the combo box.
The outline of the control changes to show the size of the combo box with the drop-down area extended.
Use the bottom sizing handle to change the initial size of the drop-down area.
Choose the drop-down arrow again to close the drop-down portion of the combo box.
Have you tried passing some other value as your second parameter in your Combo initialization (first line) ? Something other than SWT.BORDER?
I've tried finding out if it is possible to display strings in multiple rows (as a single combo box item), but with no success. This would reduce the width of your items. Try adding \n to a couple of strings that you add to the combo box, and see if it will work. If it works, you can automate this process later by parsing through the string, and checking whether the space character count gets to high and adding \n after every fifth or sixth blank character. I think codejammer's suggestion is the best one, but I can't upvote yet.
Partially solved the problem adding to item names some spaces (have set the number of spaces by trial and error). Now combo is wider and all texts are visible, however horizontal scroll is visible, too.
String p = " ";
combo.add("Long.... item name 1"+p);
combo.add("Long item name ..... 2"+p);
...
Another soultion is resize combo when it gain focus and restore size after lost focus. Example below.
final Point p = combo.getSize();
combo.addFocusListener(new FocusListener() {
#Override
public void focusLost(FocusEvent e) {
((Control) e.getSource()).setSize(p);
}
#Override
public void focusGained(FocusEvent e) {
((Control) e.getSource()).setSize(new Point(400, p.y));
}
});
combo.setPreferredSize(new Dimension(FIX_WIDTH, FIX_HEIGHT));
Try this
JComboBox CB = new JComboBox();
CB.setPreferredSize(new Dimension(int, int));
p.add(CB);// which p is a JPanel

Categories

Resources