gpt4 book ai didi

java - 在 JTable 中使用 JEditorPane 代替默认的 JLabel

转载 作者:行者123 更新时间:2023-12-02 06:44:03 25 4
gpt4 key购买 nike

尝试对 JTable 中的一列使用 JEditorPane,但没有成功。主要原因是我想添加一个 hyperLinkListener,而 JEditorPane 显然应该是比默认 JLabel 更好的选择。

private void createQueueTable (String[] columnNames){
Object[][] rows

queueModel = new DefaultTableModel(rows,columnNames){
@Override
public Class getColumnClass(int colNum) {
switch (colNum) {
case 0:
return String.class;
...
case 9:
return String.class; //Comment
default:
return String.class;
}
}
};

queueTable.setModel(queueModel)
TableColumnModel queueTableColumnModel = queueTable.getColumnModel();
TableCellRenderer tcr = new CustomTableCellRenderer();
TableCellRenderer scr = new CustomTablePaneCellRenderer();

int counter =0
while(counter<columnNames.size()-1){
queueTableColumnModel.getColumn(counter).setCellRenderer(tcr);
counter++
}

queueTableColumnModel.getColumn(counter).setCellRenderer(scr);
...
}
public class CustomTablePaneCellRenderer extends JTextPane implements TableCellRenderer {
public CustomTablePaneCellRenderer() {
setContentType("text/html");
}

public Component getTableCellRendererComponent (JTable table, Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
Component cell = super.getTableCellRendererComponent(table, obj, isSelected, hasFocus, row, column);
if (isSelected) {
}
else{
if (row % 2 == 0)
cell.setBackground(new Color(248,248,248))
else
cell.setBackground(Color.white)
}
return cell;
}
}
<小时/>
Exception in thread "AWT-EventQueue-0" groovy.lang.MissingMethodException: No signature of method: CustomTablePaneCellRenderer.getTableCellRendererComponent() is applicable for argument types: (EMSMonster$1, java.lang.String, java.lang.Boolean, java.lang.Boolean, java.lang.Integer, java.lang.Integer) values: [EMSMonster$1[,0,0,1280x304,alignmentX=0.0,alignmentY=0.0,border=,flags=251658568,maximumSize=,minimumSize=,preferredSize=,autoCreateColumnsFromModel=true,autoResizeMode=AUTO_RESIZE_OFF,cell
SelectionEnabled=true,editingColumn=-1,editingRow=-1,gridColor=javax.swing.plaf.ColorUIResource[r=122,g=138,b=153],preferredViewportSize=java.awt.Dimension[width=450,height=400],rowHeight=16,rowMargin=1,rowSelectionAllowed=true,selectionBackground=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],selectionForeground=sun.swing.PrintColorUIResource[r=51,g=51,b=51],showHorizontalLines=true,showVerticalLines=true], ...]
Possible solutions: getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodOnSuperN(ScriptBytecodeAdapter.java:130)
at CustomTablePaneCellRenderer.getTableCellRendererComponent(EMSMonster.groovy:2613)
at javax.swing.JTable.prepareRenderer(JTable.java:5731)
at javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:2114)
at javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:2016)
at javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:1812)
at javax.swing.plaf.ComponentUI.update(ComponentUI.java:161)
at javax.swing.JComponent.paintComponent(JComponent.java:778)
at javax.swing.JComponent.paint(JComponent.java:1054)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JViewport.paint(JViewport.java:731)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintChildren(JComponent.java:887)
at javax.swing.JComponent.paint(JComponent.java:1063)
at javax.swing.JComponent.paintToOffscreen(JComponent.java:5221)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(RepaintManager.java:1512)
at javax.swing.RepaintManager$PaintManager.paint(RepaintManager.java:1443)
at javax.swing.RepaintManager.paint(RepaintManager.java:1236)
at javax.swing.JComponent._paintImmediately(JComponent.java:5169)
at javax.swing.JComponent.paintImmediately(JComponent.java:4980)
at javax.swing.RepaintManager$3.run(RepaintManager.java:796)
at javax.swing.RepaintManager$3.run(RepaintManager.java:784)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:784)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:757)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:706)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:62)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1651)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:688)
at java.awt.EventQueue$3.run(EventQueue.java:686)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:697)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)

这或多或少应该是这样的。 Screenshot

阅读其他几篇文章后,我开始怀疑是否可以在同一个表格单元格中包含文本和可点击的链接。

非常感谢您的进一步帮助!!

最佳答案

Main reason for this is that I want to add a hyperLinkListener and JEditorPane should apparently be a better choice for this than the default JLabel.

我实际上会反对这一点。主要原因是,单元格渲染器只是其渲染器组件的“快照”,它不是 Activity 组件。这意味着它不会响应用户输入,例如按键或鼠标监听器。

就我个人而言,我会简单地“渲染”一个 DefaultTableCellRenderer 使其看起来像一个标准的超链接。

然后,我将建立一个“特殊”编辑器,它仅响应鼠标点击并相应地激活超链接......

例如...

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.EventObject;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;

public class TableHyperLink {

public static void main(String[] args) {
new TableHyperLink();
}

public TableHyperLink() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

try {
MyModel model = new MyModel();
JTable table = new JTable(model);
table.setDefaultRenderer(URL.class, new URLTableCellRenderer());
table.setDefaultEditor(URL.class, new URLTableCellEditor());

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (MalformedURLException exp) {
exp.printStackTrace();
}
}
});
}

public class MyModel extends DefaultTableModel {

public MyModel() throws MalformedURLException {
super(new Object[][]{{new URL("http://stackoverflow.com")}},
new Object[]{"Link"});
}

@Override
public Class<?> getColumnClass(int columnIndex) {
return URL.class; // Only have one column :P
}

@Override
public boolean isCellEditable(int row, int column) {
return true;
}

}

public class URLTableCellRenderer extends DefaultTableCellRenderer {

public URLTableCellRenderer() {
setForeground(Color.BLUE);
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); //To change body of generated methods, choose Tools | Templates.
if (value instanceof URL) {
value = "<html><u>" + ((URL)value).toString() + "</u></html>";
setText(value.toString());
}
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
return this;
}

}

public class URLTableCellEditor extends AbstractCellEditor implements TableCellEditor {

private URL url;

@Override
public Object getCellEditorValue() {
return url;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
JLabel editor = new JLabel("Clicked");
if (value instanceof URL) {
url = (URL) value;
editor.setText("<html><ul>" + url.toString() + "</ul></html>");
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
stopCellEditing();
try {
Desktop.getDesktop().browse(url.toURI());
} catch (IOException | URISyntaxException ex) {
ex.printStackTrace();
}
}
});
return editor;
}

@Override
public boolean isCellEditable(EventObject e) {
boolean editable = false;
if (e instanceof MouseEvent) {
MouseEvent me = (MouseEvent) e;
if (me.getClickCount() == 1 && SwingUtilities.isLeftMouseButton(me)) {
editable = true;
}
}
return editable;
}
}
}

您的另一个选择是将一个 MouseListener 附加到表格并监视鼠标单击。这将涉及您必须将鼠标点转换为列索引并确定该列是否是模型中的正确列,查找模型中的值,然后根据需要进行处理。

它更困惑,更不易移植并且容易出错 - 恕我直言

基于反馈的其他示例

我只是想指出这是黑客行为。 URL提取基于Handling hyperlink right clicks on a JTextPane的答案

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.AttributeSet;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;

public class TableHyperLink {

public static final String PASSWORD_PROMPT = "";

public static void main(String[] args) {
new TableHyperLink();
}

public TableHyperLink() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}

try {
MyModel model = new MyModel();
JTable table = new JTable(model);
TableColumn column = table.getColumn(table.getColumnName(0));
column.setCellEditor(new URLTableCellEditor());
column.setCellRenderer(new URLTableCellRenderer());

column = table.getColumn(table.getColumnName(1));
column.setCellEditor(new URLTableCellEditor());
column.setCellRenderer(new URLTableCellRenderer());

JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (MalformedURLException exp) {
exp.printStackTrace();
}
}
});
}

public class MyModel extends DefaultTableModel {

public MyModel() throws MalformedURLException {
super(new Object[][]{
{"<html>This is a <a href='https://stackoverflow.com/questions/18838196/using-jeditorpane-instead-of-default-jlabel-in-jtable/18838244?noredirect=1#comment27831752_18838244'>Test</a>",
"<html>This is a <a href='https://stackoverflow.com/questions/18838196/using-jeditorpane-instead-of-default-jlabel-in-jtable/18838244?noredirect=1#comment27831752_18838244'>Test</a>"}},
new Object[]{"Link", "Link1"});
}

@Override
public Class<?> getColumnClass(int columnIndex) {
return String.class; // Only have one column :P
}

@Override
public boolean isCellEditable(int row, int column) {
return true;
}

}

/**
* JEditorPane based renderer. This gives me issues with fonts, so
* you may need to do some more playing around with this to
* get it to work the way you want
*/
public class URLTableCellRenderer extends JEditorPane implements TableCellRenderer {

public URLTableCellRenderer() {
// Set the content type
setContentType("text/html");
// Get rid of the default border
setBorder(new EmptyBorder(1, 1, 1, 1));
// Get rid of any margins
setMargin(new Insets(0, 0, 0, 0));
}

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
setText(value == null ? null : value.toString());
return this;
}

}

/**
* Drop in editor, this really is just a event factory used to capture the events
* and process them...
*/
public class URLTableCellEditor extends AbstractCellEditor implements TableCellEditor {

// This is the value returned to the table model, because I've used a DefaultTableModel
// this is very important
private Object value;
// The point that the mouse click occured
private Point clickPoint;
// The url to open
private URL url;

@Override
public Object getCellEditorValue() {
return value;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
// Capture the current cell value
this.value = value;
// Something to return to the table...
JLabel editor = new JLabel(value == null ? null : value.toString());

// Get the cell renderer for the current cell
TableCellRenderer renderer = table.getCellRenderer(row, column);
// Get the cell component for the renderer (expecting a JEditorPane)
Component comp = table.prepareRenderer(renderer, row, column);
// Set the bounds of the component to meet the requirements for the cell rect
comp.setBounds(table.getCellRect(row, column, false));
if (comp instanceof JEditorPane) {
// Get the JEditorPane
JEditorPane editPane = (JEditorPane) comp;
// Asdjust the click point to be within the
// editor context
clickPoint.x -= comp.getLocation().x;
clickPoint.y -= comp.getLocation().y;
try {
// Try and get the hyperlink that was clicked
url = getHyperlink(editPane, clickPoint);
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
}

SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// Dispose of the editor...
// You could use cancelCellEditing() instead and the table won't
// try and update the model...
stopCellEditing();
// Open the URL if possible
if (url != null) {
try {
Desktop.getDesktop().browse(url.toURI());
} catch (IOException | URISyntaxException ex) {
ex.printStackTrace();
}
}
}
});
return editor;
}

@Override
public boolean isCellEditable(EventObject e) {
boolean editable = false;
if (e instanceof MouseEvent) {
MouseEvent me = (MouseEvent) e;
if (me.getClickCount() == 1 && SwingUtilities.isLeftMouseButton(me)) {
editable = true;
// We need to the point that the mouse event occured...
clickPoint = me.getPoint();
}
}
return editable;
}

/*
* Try and extract the URL from the hyperlink at the given point
*/
protected URL getHyperlink(JEditorPane editor, Point p) throws MalformedURLException {
int pos = editor.viewToModel(p);
return getHyperlink(editor.getDocument(), pos);
}

/*
* Get the hyperlink from the supplied document at the given position in the document
*/
protected URL getHyperlink(Document doc, int pos) throws MalformedURLException {
URL url = null;
Element h = getHyperlinkElement(doc, pos);
if (h != null) {
Object attribute = h.getAttributes().getAttribute(HTML.Tag.A);
if (attribute instanceof AttributeSet) {
AttributeSet set = (AttributeSet) attribute;
String href = (String) set.getAttribute(HTML.Attribute.HREF);
if (href != null) {
url = new URL(href);
}
}
}
return url;
}

/*
* Get the element from the document that represents a hyperlink based on the position
* within teh document. null if it's not a hyperlink element...
*/
protected Element getHyperlinkElement(Document doc, int pos) {
if (pos >= 0 && doc instanceof HTMLDocument) {
HTMLDocument hdoc = (HTMLDocument) doc;
Element elem = hdoc.getCharacterElement(pos);
if (elem.getAttributes().getAttribute(HTML.Tag.A) != null) {
return elem;
}
}
return null;
}
}
}

关于java - 在 JTable 中使用 JEditorPane 代替默认的 JLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18838196/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com