/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package texteditor;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
/**
*
* @author
*/
public class TextPad implements DocumentListener,ChangeListener{
private JTextPane textArea;
private Document textDoc;
private int selectionOffset;
private int selectionLength;
public void init()
{
//System.out.println("Constructor invoked");
// TODO code application logic here
JFrame window = new JFrame("Text Editor");
//JMenuBar menuBar = window.getJMenuBar();
/**
//Create menu bar
JMenuBar menuBar= new JMenuBar();
//File Menu
JMenu fileMenu = new JMenu("File");
fileMenu.add(new JMenuItem("Save"));
* */
// menuBar.add(fileMenu);
//window.setJMenuBar(menuBar);
this.textArea= new JTextPane();
this.textDoc = this.textArea.getDocument();
this.textDoc.addDocumentListener(this);
this.textArea.getCaret().addChangeListener(this);
//System.out.println(d.getClass());
//override default text generation ****THIS LINE******
((AbstractDocument)this.textDoc).getDocumentFilter();
//Add scorllable interface in jtextpane
window.add(new JScrollPane(this.textArea));
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
public void changedUpdate(DocumentEvent e)
{
//System.out.println("changed");
}
public void removeUpdate(DocumentEvent e)
{
System.out.println("removed");
}
public void insertUpdate(DocumentEvent e)
{
try
{
System.out.println(this.textDoc.getText(0,this.textDoc.getLength()));
}
catch(Exception ex)
{
System.err.println(ex);
}
}
/**
*
* @param e
*/
public void stateChanged(ChangeEvent e)
{
System.out.println(this.textArea.getCaret().getMark());
}
}
为什么将abstractDocument
作为((AbstractDocument)this.textDoc).getDocumentFilter();
进行投射可以正常工作,但不会像对待它一样
this.textDoc.getDocumentFilter();
确实会发现无法找到该方法的错误。有人可以解释一下吗?
修改
if(this.textDoc instanceof AbstractDocument)
{
System.out.println("Yes it is");
}
打印Yes it is
,这也暗示它有点AbstractDocument
。我不明白为什么调用AbstractDocument
的方法会引发错误。
答案 0 :(得分:2)
HoverCraft说得对。使用Java,您只能根据对象的方式访问对象的方法和属性。所以,要演示
public interface Fooer {
public int doFoo();
}
public class Foo implements Fooer{
public int doFoo(){return 0;}
public void doNoFooer(){}
}
public class Bar extends Foo {
public void doYesFooer(){}
}
如果您使用这些定义,将会发生以下情况:
Foo foo = new Bar();
foo.doNoFooer(); // fine because it is a method of Foo
foo.doFoo();
foo.doYesFooer(); // causes an error because the variable is improperly typed.
Fooer fooer = foo;
fooer.doFoo(); // find because it is part of the definition of Fooer
fooer.doYesFoo(); // causes an error because the variable is improperly typed.
fooer.doNoFoo(); // causes an error because the variable is improperly typed.
Bar bar = (Bar) foo;
// notice that the next three do not cause errors.
bar.doYesFooer();
bar.doNoFooer();
bar.doFoo();
答案 1 :(得分:0)
要扩展cwallenpoole的上一个答案并给出为什么 Java以这种方式工作的原因,请考虑以下代码片段
class Foo {
int doFoo() {return 0;}
}
class Bar extends Foo {
int doBar() {return 1;}
}
class FooBar {
static int useBar(Foo foo) {
((Bar) foo).doBar();
}
}
Bar someBar = new Bar();
Foo someFoo = new Foo();
FooBar.useBar(someBar) // compiles, no runtime error
FooBar.useBar(someFoo) // compiles, runtime error
Java的类型系统旨在使第二次调用成为编译时错误,而不是可能难以调试的运行时错误。显然,在这个例子中,调试或者可能添加一个检查实例并不困难。但是,使用强制转换会使类型系统失败,并且还会破坏类型系统为程序员提供的任何编译时安全性,这是首先使用静态类型语言的主要原因之一。
要明确,以下是编译时错误,警告程序员基于变量的类型,变量不一定具有该函数,即使子类定义它。
class FooBar {
static int useBar(Foo foo) {
foo.doBar();
}
}