我认为最好在示例程序代码中显示以下情况。我有一个扩展JPanel
的Java类。在这个类中有两个对象,还有两个JPanels
。其中一个JPanel
个对象是JTable
个对象。我为这个检测到双击的JTable
添加了一个监听器。当它检测到双击时,我想在顶级类中触发一个方法。如何在Java中引用此方法?
public class TopPanel extends JPanel {
JPanel OnePanel;
JPanel TwoPanel;
public void MethodToFire;
}
public class OnePanel extends JPanel {
JTable TheTable;
}
public class TheTable extends JTable {
public TheTable {
this.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2){ SYNTAX CALLING THE METHOD IN TopPanel }
}
} );
}
}
答案 0 :(得分:7)
解决此问题的一种方法是使用合成而不是继承。您可以将JPanel传递给JTable的子类。
public class TopPanel extends JPanel
{
private TheTable table;
public TopPanel()
{
table = new TheTable(this);
}
public void methodToFire() { }
}
public class TheTable extends JTable
{
private TopPanel panel;
public TheTable(TopPanel panel)
{
this.panel = panel;
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
doThing();
}
} );
}
private void doThing()
{
this.panel.methodToFire();
}
}
答案 1 :(得分:4)
要访问Outer类的方法,您需要使用Outer.this.method()的语法。
因此,在这种情况下,要从侦听器访问“TheTable”类的方法,您应该使用TheTable.this.callMethod()
。
我认为TopPanel
已将TheTable
添加到其中。在这种情况下,您可以执行以下操作:
mouseClicked(...) {
TopTable t = (TopTable)TheTable.this.getParent();
t.MethodToFire();
}
这是对这个问题的直接回答,不一定是“最好”的方法。类型安全的组合方法将是一个更好的长期解决方案。
答案 2 :(得分:2)
好像你正在走一条路 - 为什么不做最外层的一切呢?毕竟,这是听众存在的一个原因:
public class TopPanel {
public TopPanel() {
// Construct everything here
OnePanel.TheTable.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
if (e.getClickCount() == 2){ MethodToFire }
}
} );
}
}
答案 3 :(得分:2)
当您按下鼠标时,您可以使您的TheTable触发事件,TopPanel可以监听。这样做的好处是不会使Table和Panel类彼此依赖。
代码涉及更多,但解耦可能是值得的。
public class TopPanel extends JPanel
{
private TheTable table;
public TopPanel()
{
table = new TheTable(this);
table.addTheTableListener(new TheTableListener() {
public void tableSelected() { // or tableSelected(TableSelectionEvent e) if you want to make a TableSelectionEvent
methodToFire();
}
});
}
public void methodToFire() { }
}
public class TheTable extends JTable
{
private TopPanel panel;
private EventListenerList listeners;
public TheTable(TopPanel panel)
{
this.panel = panel;
listeners = new EventListenerList();
this.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
fireTableSelected();
}
} );
}
public void addTheTableListener(TheTableListener l) {
listeners.add(l);
}
// also write removeListener
private void fireTableSelected()
{
for (TheTableListener l : listeners) {
l.tableSelected();
}
}
public interface TheTableListener extends EventListener
{
public void tableSelected();
}
答案 4 :(得分:0)
我不认为Java有这样做的直接语法,除非你开始玩反射(这当然是可能的,但我不认为它非常干净)。
在您想要进行调用的位置,您的“this”指的是MouseAdapter的匿名子类。
最干净的方法可能是创建一个私有方法,让我们在TheTable中调用它,并让适配器调用该函数。
现在,因为方法X在TheTable中,它不知道它在一个面板内,所以它没有任何方法来激活该功能。如果您确定每个表都在一个面板中,那么您可以向Table类添加一个面板引用字段,在创建它时初始化它(您可能需要在OnePanel上修改构造函数),然后从中调用TheTable中的方法。
如果您最终尝试探索不属于JPanel的面板方法,则可能需要创建并传递接口。