我有一个带有自定义单元格渲染器的JTable。我正在将一个包含多个JLabel的面板添加到JTable中。问题是,当鼠标悬停在每个JLabel上时,我似乎无法获得每个工具的工具提示。我不想设置jpanel工具提示,我想显示我在jpanel内的3个JLabel上设置的工具提示。
继承我的JTable初始化:
public static JTable users = new JTable(model) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public Class<? extends Object> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public String getToolTipText(MouseEvent event) {
String tip = null;
Point p = event.getPoint();
// Locate the renderer under the event location
int hitColumnIndex = columnAtPoint(p);
int hitRowIndex = rowAtPoint(p);
if (hitColumnIndex != -1 && hitRowIndex != -1) {
TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
Rectangle cellRect = getCellRect(hitRowIndex, hitColumnIndex, false);
component.setBounds(cellRect);
component.validate();
component.doLayout();
p.translate(-cellRect.x, -cellRect.y);
Component comp = component.getComponentAt(p);
if (comp instanceof JComponent) {
return ((JComponent) comp).getToolTipText();
}
}
// No tip from the renderer get our own tip
if (tip == null) {
tip = getToolTipText();
}
return tip;
}
};
和我的自定义单元格渲染代码:
public class TransparentRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
public JPanel p = new JPanel();
........
// This method is called each time a cell in a column
// using this renderer needs to be rendered.
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
....
// Now lets color in the table accordingly..
if (value.toString().equals(gmeLobby.user)) {
JLabel l = new JLabel(value.toString());
l.setForeground(Color.YELLOW);
p.add(l);
//setHorizontalAlignment(SwingConstants.LEFT);
} else {
// If username is not yours
//setHorizontalAlignment(SwingConstants.LEFT);
if(value instanceof ImageIcon)
{
final JLabel l = new JLabel();
l.setIcon((ImageIcon) value);
l.setAlignmentY(0.85f);
l.setToolTipText(((ImageIcon) value).getDescription());
p.add(l);
if(vColIndex==0)
{
final JLabel w = new JLabel();
final JLabel d = new JLabel();
try {
w.setIcon(gmeImages.gmeImages("globe"));
w.setToolTipText(((ImageIcon) value).getDescription());
d.setIcon(gmeImages.gmeImages("dnds"));
d.setToolTipText(((ImageIcon) value).getDescription());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.add(d);
p.add(w);
setPosition(w, 5, 0);
setPosition(d, 15, 2);
}
setPosition(l, 0, 0);
}else{
JLabel l = new JLabel(value.toString());
l.setForeground(Color.WHITE);
p.add(l);
}
return p;
}
if (isSelected) {
setBackground(new Color(rsbc.getRed() - 100, rsbc.getGreen(), rsbc.getBlue()));
} else {
setBackground(bgu);
}
if (hasFocus) {
// this cell is the anchor and the table has the focus
p.setBackground(new Color(rsbc.getRed() - 100, rsbc.getGreen(), rsbc.getBlue()));
}
// Since the renderer is a component, return itself
return this;
}
任何帮助都会很棒。 JTable上工具提示的当前覆盖似乎只是添加了第一个组件的工具提示。
由于
编辑:
感谢所有帮助过的人,在安德里亚评论SSCCE时,我似乎解决了问题,不确定错误是什么,我相信这可能与我初始化imageicon变量的方式有关
无论如何,每个图像上有一个工具提示的单元格中包含2个图像的示例程序如下:
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.MatteBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.BadLocationException;
@SuppressWarnings("serial")
public class design extends JFrame{
// Create the JTable users list and set editable to false
public static DefaultTableModel model = new DefaultTableModel();
public static JTable users = new JTable(model) {
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
@Override
public Class<? extends Object> getColumnClass(int column) {
return getValueAt(0, column).getClass();
}
@Override
public String getToolTipText(MouseEvent event) {
String tip = null;
Point p = event.getPoint();
// Locate the renderer under the event location
int hitColumnIndex = columnAtPoint(p);
int hitRowIndex = rowAtPoint(p);
if (hitColumnIndex != -1 && hitRowIndex != -1) {
TableCellRenderer renderer = getCellRenderer(hitRowIndex, hitColumnIndex);
Component component = prepareRenderer(renderer, hitRowIndex, hitColumnIndex);
Rectangle cellRect = getCellRect(hitRowIndex, hitColumnIndex, false);
component.setBounds(cellRect);
component.validate();
component.doLayout();
p.translate(-cellRect.x, -cellRect.y);
Component comp = component.getComponentAt(p);
if (comp instanceof JComponent) {
return ((JComponent) comp).getToolTipText();
}
}
// No tip from the renderer get our own tip
if (tip == null) {
tip = getToolTipText();
}
return tip;
}
};
/**
* @param args
* @throws Exception
*/
public design() throws Exception
{
initialize();
setSize(400, 400);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
add(users);
setVisible(true);
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
new design();
}
public static void initialize() throws Exception
{
model.addColumn("icons");
model.addColumn("text");
users.setRowHeight(40);
TableColumn col = users.getColumnModel().getColumn(0);
col.setCellRenderer(new TransparentRenderer());
TableColumn col2 = users.getColumnModel().getColumn(1);
col2.setCellRenderer(new TransparentRenderer());
model.addRow(new Object[] { new ImageIcon(), "text here" });
}
}
class TransparentRenderer extends JPanel implements TableCellRenderer {
private static final long serialVersionUID = 1L;
public JPanel p = new JPanel();
private static SpringLayout spring = new SpringLayout();
public TransparentRenderer() throws Exception, BadLocationException {p.setLayout(spring);}
// This method is called each time a cell in a column
// using this renderer needs to be rendered.
@Override
public Component getTableCellRendererComponent(JTable table, Object value,
boolean isSelected, boolean hasFocus, int rowIndex, int vColIndex) {
if(value instanceof ImageIcon)
{
if(vColIndex==0)
{
JLabel w = new JLabel();
JLabel d = new JLabel();
try {
ImageIcon icon1 = new ImageIcon();
extracted("http://fxtrade.oanda.com/wandacache/star_icon-c10fffd09c7a7548f329f56e446f3cfe5463558b.png"
, icon1, "Tooltip for icon 1");
ImageIcon icon2 = new ImageIcon();
extracted("http://hotels.online.com.sg/DB/icon/star_icon2.gif"
, icon2, "Tooltip for icon 2");
w.setIcon(icon1);
w.setToolTipText("ToolTip 1");
d.setIcon(icon2);
d.setToolTipText("ToolTip 2");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
p.add(d);
p.add(w);
setPosition(d, 5, 2);
setPosition(w, 5, 0);
}
return p;
}else{
add(new JLabel(value.toString()));
}
return this;
}
public void setPosition(JComponent c, int w, int n)
{
spring.putConstraint(SpringLayout.WEST, c, w, SpringLayout.WEST, p);
spring.putConstraint(SpringLayout.NORTH, c, n, SpringLayout.NORTH, p);
}
public void extracted(String link, ImageIcon icon, String desc) throws Exception
{
BufferedImage image = ImageIO.read(new URL(link));
icon.setImage(image);
if(desc.equals("")){} else{ icon.setDescription(desc);}
}
}
感谢所有帮助过的人:)
答案 0 :(得分:0)
您的代码是否有效? TransparentRenderer
是每列的单例,并且逐行为每个单元格调用getTableCellRendererComponent
。似乎将要渲染新子节点的每个单元格添加到变量p
中。这可能就是为什么你总是只看到第一个组件的原因。