欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Fully Interactive JTables (aka Mouseover Edi

系統 2137 0

?

在學Swing的時候,因為想寫一個表格里面鑲嵌其他組建的功能。找到老外一片文章,如下:

原文: http://blog.palantirtech.com/2007/05/17/jtable-mouseover-editing/

?

-------------------------------------------------------------------------------------------------

?

May 17th, 2007 | Kevin

What sucks about JTables ? Everything, of course—but that’s a developer’s perspective. To the user, cell editing is rough around the edges: when and where to click, and how many times—it’s never perfectly clear. Cells in a table just don’t provide the mouseover feedback that regular components do. If only a JTable behaved like a bunch of components thrown into a giant GridBag or TableLayout

Mouseover Editing simulates just that. The idea is to attach a MouseListener to the JTable and call editCellAt(row, col) whenever the cursor moves over a new cell. In other words, even though only one cell in a table can be fully interactive (the editing cell) at any given time, as long as we keep moving that cell to stay underneath the user’s cursor, the whole table will appear to be fully interactive. If done correctly, this will appear to the user as though he’s interacting with a bunch of real components (rather than rendered stamps) inside a giant Grid/GridBag/TableLayout.

Most importantly, the user will get mouseover feedback about which cells are editable, and how to edit them. Checkboxes, buttons, and comboboxes (if the L&F supports it) will highlight to indicate press-ability and the cursor will turn to a text caret when hovering over cells that contain textfields. When done correctly, the effect is nearly seamless and very satisfying.

Here’s a webstart demo . Read on for the solution in code.

?

There are three parts to the Mouseover Editing solution (over and above what’s needed for typical JTable editing).

Part 1: Identical Editors and Renderers

This is important. Typically, a table will use a JLabel to render a cell and a JTextField to edit the cell. When the editor is swapped in to replace the renderer, there’s a slight flicker—the textfield might have a different background color, the text mayb be in a slightly different location, etc. This is all well and good when the user has to click or double-click to engage the editor, because the click can be perceived as granting permission to the program to do something on its own. However, a simple mouseover is a different story. Here, the look, feel, and placement of the editor should exactly match up with the look, feel, and placement of the renderer; otherwise, there will be a flicker trail every time the cursor passes through the JTable.

In order to make editors and renderers look and behave identically, (a) we need them to start out identical and (b) we need to apply the same transformations to them.

The easiest way to make an identical editor and renderer is to produce two objects from a combined EditorRenderer class. Here’s how that might work for a checkbox:

          public class CheckBoxEditorRenderer extends AbstractCellEditor implements TableCellRenderer
{
	private JCheckBox checkbox = new JCheckBox();
	public CheckBoxEditorRenderer() {
		super();
		checkbox.setFocusable(false);
	}
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
		if (value instanceof Boolean) {
			checkbox.setSelected((Boolean) value);
		}
		return checkbox;
	}
	public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
		if (value instanceof Boolean) {
			checkbox.setSelected((Boolean) value);
		}
		return checkbox;
	}
	public Object getCellEditorValue() {
		return checkbox.isSelected();
	}
}


        
?

Notice how CheckBoxEditorRenderer implements both the TableCellRenderer and TableCellEditor interfaces (the latter via AbstractCellEditor ).

Editors and renderers must also be subjected to the same transformations. In a subclass of JTable, say one called MouseoverJTable, use the following format for your prepareEditor() and prepareRenderer() methods:

    public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
	Component c = super.prepareRenderer(renderer, row, column);
	return prepareEditorRenderer(c, row, column);
	}
	public Component prepareEditor(TableCellEditor editor, int row, int column) {
	Component c = super.prepareEditor(editor, row, column);
	return prepareEditorRenderer(c, row, column);
	}
	private Component prepareEditorRenderer(Component stamp, int row, int column) {
//	 ...  All sorts of shenanigans can go on here.
	}
}

  
?

?

This ensures that both the editor and the renderer will go through the same decoration path.

Part 2: Two-stage editing

What we’ve presented thus far works really well for buttons and checkboxes, which are minimally interactive. With comboboxes and textfields, there’s a problem. Suppose you mouse over a cell with a combobox. First the combobox will become highlighted (if the L&F supports it) to indicate that it’s clickable; this is expected and reasonable behavior. If you click on it, the combobox flyout will appear; this is also expected and reasonable behavior. Now move your mouse just a little bit…. oh no! You accidentally moused over another cell, and the table decided to swap out the editor you were using (the combobox) and swap in a new editor. Goodbye flyout.

To make sure this doesn’t happen, we need editors with two states: temporarily engaged and fully engaged. When the cursor first moves over a cell, we call editCellAt(r, c), and plop the editor into place, temporarily engaged. This means it’s an interactive JComponent that responds to mouse events, but that it’s okay to swap it out and replace it with a new editor if the cursor changes location. Then, if the user starts interacting with the Editor in a way that requires the editor to keep around a bit of state (like the visibility of a flyout for a combobox), we say that the editor is fully engaged, and that the table isn’t allowed to swap it out until the user disengages it.

What this looks like in code:

    public interface TwoStageTableCellEditor extends TableCellEditor
{
    public boolean isFullyEngaged();
}

  
?
    public class ComboBoxEditorRenderer extends AbstractCellEditor implements TwoStageTableCellEditor, TableCellRenderer
{
    private JComboBox combobox;
    ...
    public Object getCellEditorValue() {
        return combobox.getSelectedItem();
    }
    public boolean isFullyEngaged() {
        return combobox.isPopupVisible();
    }
}


  
?

Part 3: Mouseover swapping

Here’s where it all comes together. Mouseover swapping is what your (subclass of) JTable does in order to keep track of which cell is being edited, where the cursor is, and whether to swap the editor from one cell to another. This is kind of boring, and only really makes sense in code, so here you go:

?

    // In the constructor...
// listeners for two-stage editing
this.addMouseListener(twoStageEditingListener);
this.addMouseMotionListener(twoStageEditingListener);


  

?

    // In the body of your JTable subclass...
private final FullMouseAdapter twoStageEditingListener = new FullMouseAdapter() {
    public void mouseMoved(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseEntered(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseExited(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseClicked(MouseEvent e) {
        possiblySwitchEditors(e);
    }
};
private void possiblySwitchEditors(MouseEvent e) {
    Point p = e.getPoint();
    if (p != null) {
        int row = rowAtPoint(p);
        int col = columnAtPoint(p);
        if (row != getEditingRow() || col != getEditingColumn()) {
            if (isEditing()) {
                TableCellEditor editor = getCellEditor();
                if (editor instanceof TwoStageTableCellEditor && !((TwoStageTableCellEditor)editor).isInStageTwo()) {
                    if (!editor.stopCellEditing()) {
                        editor.cancelCellEditing();
                    }
                }
            }

            if (!isEditing()) {
                if (row != -1 && isCellEditable(row, col)) {
                    editCellAt(row, col);
                }
            }
        }
    }
}


  
?

Conclusion

This solution works pretty well. There are a couple flaws (e.g. start editing a textfield and then mouseover a button—no feedback, because the text field is fully engaged), but overall it is much better than an unadorned JTable, and not too much of a burden on the developer. Be warned, though: it may wreak havoc on the focus system.

Extra credit: Is it possible to achieve a similar effect by forwarding MouseEvents through to the renderers/stamps?

Fully Interactive JTables (aka Mouseover Editing)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久国产精品 | 欧美日韩一区二区三区在线观看 | 午夜精品一区二区三区免费视频 | 中文在线一区二区 | 6080yy精品一区二区三区 | 国产真实乱子伦清晰对白 | 色接久久 | 亚洲精品久久久久中文字幕欢迎你 | 日本超碰 | 精品久久久久久免费影院 | 色婷婷综合缴情综六月 | 国产精品中文在线 | 中文字幕 国产精品 | 天天影视色香欲综合网老头 | 国产亚洲精品久久久极品美女 | 99re国产| 精品免费国产一区二区三区四区 | 日韩一区二区在线视频 | 免费精品美女久久久久久久久久 | 手机在线观看你懂得 | 精品视频在线播放 | 日韩国产第一页 | 成a人v在线观看视频 | 国产精品成人亚洲一区二区 | 亚洲欧美视频网站 | 色婷婷综合久久久久中文一区二区 | 一97日本道伊人久久综合影院 | 一区中文字幕 | 亚洲精品久久久久无码AV片软件 | 在线观看av网站永久 | 国产精品免费一区 | 激情97 | 国产大陆精品另类xxxx | 亚洲三级视频 | 日韩欧美视频一区二区三区 | 午夜亚洲福利 | 在线一区二区三区 | 欧美一级黄视频 | 亚洲一区在线免费 | 毛片在线视频观看 | 欧美视屏一区二区 |