How can I add JTextField to JLabel? (in TreeCellEditor)

Now, I'm implementing the TreeCellEditor interface.

I need to add theJTextField to theJLabel as follows.

class MyCellEditorextends JLabelimplements TreeCellEditor

{

JTextField editor;

...

privatevoid prepareEditor()

{

...

editor =new JTextField(str);

add(editor);

revalidate();

...

}

...

}

But, The JTextField don't appear! Why?

[768 byte] By [sjjung] at [2007-9-26 1:27:12]
# 1

Hi sijung,

Please refer this code.

import java.awt.*;

import java.awt.event.*;

import java.util.*;

import javax.swing.*;

import javax.swing.border.*;

import javax.swing.event.*;

import javax.swing.tree.*;

public class AncestorTree extends JFrame

{

public static ImageIcon ICON_SELF =

new ImageIcon("myself.gif");

public static ImageIcon ICON_MALE =

new ImageIcon("male.gif");

public static ImageIcon ICON_FEMALE =

new ImageIcon("female.gif");

protected JTree m_tree;

protected DefaultTreeModel m_model;

protected IconCellRenderer m_renderer;

protected IconCellEditor m_editor;

public AncestorTree() {

super("Ancestor Tree");

setSize(500, 400);

DefaultMutableTreeNode top = new DefaultMutableTreeNode(

new IconData(ICON_SELF, "Myself"));

addAncestors(top);

m_model = new DefaultTreeModel(top);

m_tree = new JTree(m_model);

m_tree.getSelectionModel().setSelectionMode(

TreeSelectionModel.SINGLE_TREE_SELECTION);

m_tree.setShowsRootHandles(true);

m_tree.setEditable(true);

m_renderer = new IconCellRenderer();

m_tree.setCellRenderer(m_renderer);

m_editor = new IconCellEditor(m_tree);

m_tree.setCellEditor(m_editor);

m_tree.setInvokesStopCellEditing(true);

m_tree.addMouseListener(new TreeExpander());

JScrollPane s = new JScrollPane();

s.getViewport().add(m_tree);

getContentPane().add(s, BorderLayout.CENTER);

WindowListener wndCloser = new WindowAdapter() {

public void windowClosing(WindowEvent e) {

System.exit(0);

}

};

addWindowListener(wndCloser);

setVisible(true);

}

public boolean addAncestors(DefaultMutableTreeNode node) {

if (node.getChildCount() > 0)

return false;

Object obj = node.getUserObject();

if (obj == null)

return false;

node.add(new DefaultMutableTreeNode( new IconData(

ICON_MALE, "Father of: "+obj.toString()) ));

node.add(new DefaultMutableTreeNode( new IconData(

ICON_FEMALE, "Mother of: "+obj.toString()) ));

return true;

}

public static void main(String argv[]) { new AncestorTree(); }

class TreeExpander extends MouseAdapter

{

public void mouseClicked(MouseEvent e) {

if (e.getClickCount() == 2) {

TreePath selPath = m_tree.getPathForLocation(

e.getX(), e.getY());

if (selPath == null)

return;

DefaultMutableTreeNode node =

(DefaultMutableTreeNode)(selPath.

getLastPathComponent());

if (node!=null && addAncestors(node)) {

m_tree.expandPath(selPath);

m_tree.repaint();

}

}

}

}

}

// Classes IconCellRenderer and IconData are

// unchanged from previous examples, and are

// not listed here to conserve space.

class IconCellEditor extends JLabel

implements TreeCellEditor, ActionListener

{

protected JTree m_tree = null;

protected JTextField m_editor = null;

protected IconData m_item = null;

protected int m_lastRow = -1;

protected long m_lastClick = 0;

protected Vector m_listeners = null;

public IconCellEditor(JTree tree) {

super();

m_tree = tree;

m_listeners = new Vector();

}

public Component getTreeCellEditorComponent(JTree tree,

Object value, boolean isSelected, boolean expanded,

boolean leaf, int row)

{

if (value instanceof DefaultMutableTreeNode) {

DefaultMutableTreeNode node =

(DefaultMutableTreeNode)value;

Object obj = node.getUserObject();

if (obj instanceof IconData) {

IconData idata = (IconData)obj;

m_item = idata;

// Reserve some more space...

setText(idata.toString()+"");

setIcon(idata.m_icon);

setFont(tree.getFont());

return this;

}

}

// We don't support other objects...

return null;

}

public Object getCellEditorValue() {

if (m_item != null && m_editor != null)

m_item.m_data = m_editor.getText();

return m_item;

}

public boolean isCellEditable(EventObject evt) {

if (evt instanceof MouseEvent) {

MouseEvent mEvt = (MouseEvent)evt;

if (mEvt.getClickCount() == 1) {

int row = m_tree.getRowForLocation(mEvt.getX(), mEvt.getY());

if (row != m_lastRow) {

m_lastRow = row;

m_lastClick = System.currentTimeMillis();

return false;

}

else if (System.currentTimeMillis()-m_lastClick > 1000)

{

m_lastRow = -1;

m_lastClick = 0;

prepareEditor();

mEvt.consume();

return true;

}

else

return false;

}

}

return false;

}

protected void prepareEditor() {

if (m_item == null)

return;

String str = m_item.toString();

m_editor = new JTextField(str);

m_editor.addActionListener(this);

m_editor.selectAll();

m_editor.setFont(m_tree.getFont());

add(m_editor);

revalidate();

TreePath path = m_tree.getPathForRow(m_lastRow);

m_tree.startEditingAtPath(path);

}

protected void removeEditor() {

if (m_editor != null) {

remove(m_editor);

m_editor.setVisible(false);

m_editor = null;

m_item = null;

}

}

public void doLayout() {

super.doLayout();

if (m_editor != null) {

int offset = getIconTextGap();

if (getIcon() != null)

offset += getIcon().getIconWidth();

Dimension cSize = getSize();

m_editor.setBounds(offset, 0, cSize.width - offset,

cSize.height);

}

}

public boolean shouldSelectCell(EventObject evt) { return true; }

public boolean stopCellEditing() {

if (m_item != null)

m_item.m_data = m_editor.getText();

ChangeEvent e = new ChangeEvent(this);

for (int k=0; k<m_listeners.size(); k++) {

CellEditorListener l = (CellEditorListener)m_listeners.

elementAt(k);

l.editingStopped(e);

}

removeEditor();

return true;

}

public void cancelCellEditing() {

ChangeEvent e = new ChangeEvent(this);

for (int k=0; k><m_listeners.size(); k++) {

CellEditorListener l = (CellEditorListener)m_listeners.

elementAt(k);

l.editingCanceled(e);

}

removeEditor();

}

public void addCellEditorListener(CellEditorListener l) {

m_listeners.addElement(l);

}

public void removeCellEditorListener(CellEditorListener l) {

m_listeners.removeElement(l);

}

public void actionPerformed(ActionEvent e) {

stopCellEditing();

m_tree.stopEditing();

}

}

I hope this will give you some idea.

Thanks

Bakrudeen

>

bakrudeen_indts at 2007-6-29 1:11:10 > top of Java-index,Archived Forums,Swing...
# 2

What a coincidence! ;-)

It was the very code that gave me a question.

How can be the JTextField added to JLabel?

In fact, adding the JTextField to JLabel has no effect in this simple code:

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class MyLabel extends JFrame {

private JLabel label;

public MyLabel()

{

init();

}

private void init()

{

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) { System.exit(0); }

});

label = new JLabel("test");

getContentPane().add(label);

JButton button = new JButton("add JTextField!");

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

label.add(new JTextField("text field"));

label.setText("JTextField added! but where is it?");

label.revalidate();

MyLabel.this.pack();

}

});

getContentPane().add(button, BorderLayout.SOUTH);

pack();

setVisible(true);

}

public static void main(String[] args)

{

new MyLabel();

}

}

But, the 'AncestorTree' example appears to be able to do the thing like the above.

What's the difference?

Regards,

Seung-Jin Jung

sjjung at 2007-6-29 1:11:10 > top of Java-index,Archived Forums,Swing...
# 3

The only difference I have found that can have something to be with showing or not the JTextField is the doLayout() method. Whatever, seems to me that there is no reason to extend JLabel to create a cell editor, except that you want it to be also a renderer.

If I'm right, doLayout() is where you have to place the component you want to be the editor and has been created in prepareEditor().

llturro at 2007-6-29 1:11:10 > top of Java-index,Archived Forums,Swing...
# 4

Thanks for your words, bakrudeen_indts and llturro!

Roughly, this code is what I want, although there remain somethings to be improved.import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class MyLabelApp extends JFrame {

private MyLabel label;

public MyLabelApp()

{

init();

}

private void init()

{

addWindowListener(new WindowAdapter() {

public void windowClosing(WindowEvent e) { System.exit(0); }

});

label = new MyLabel("test");

getContentPane().add(label);

JButton button = new JButton("add JTextField!");

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

label.add(new JTextField("text field"));

label.setText(";-)");

label.revalidate();

label.repaint();

MyLabelApp.this.pack();

}

});

getContentPane().add(button, BorderLayout.SOUTH);

pack();

setVisible(true);

}

public static void main(String[] args)

{

new MyLabelApp();

}

}

class MyLabel extends JLabel {

private JTextField editor;

public MyLabel(String str)

{

super(str);

}

public void add(JTextField editor)

{

super.add(editor);

this.editor = editor;

}

public void doLayout() // Secrets are here.

{

super.doLayout();

if (editor != null)

{

int offset = 20;

Dimension cSize = getSize();

editor.setBounds(offset, 0, cSize.width - offset, cSize.height);

}

}

}

sjjung at 2007-6-29 1:11:10 > top of Java-index,Archived Forums,Swing...