我代码中有这样两个函数(是我自己为了对比而写的)1. public void containerClass(){
2. JPanel jp_container = new JPanel(){
3. public void setBackground(Color bg) {
4. super.setBackground(Color.BLUE);
5. }
6. public Component add(Component comp) {
7. JLabel jl = new JLabel("你好!") ;
8. return super.add(jl);
9. }
10. } ;
11. add(jp_container) ;
12. }
13. public void commonClass(){
14. JPanel jp_common = new JPanel();
15. jp_common.setBackground(Color.red) ;
16. add(jp_common) ;
17.
18. JLabel jl = new JLabel("Welcome!") ;
19. jp_common.add(jl) ;
20. }结果,containerClass(){}不显示【你好!】两个字,问题:
1、containerClass(){}不显示【你好!】两个字,即使把JLabel jl放在内部类的最外面也不行!为什么?怎么改?2、commonClass(){}中,我重新写了些,大家看下:1. public void commonClass(){
2. JPanel jp_common = new JPanel();
3. jp_common.setBackground(Color.red) ;
4. add(jp_common) ;
5.
6. JLabel jl = new JLabel("Welcome!") ;
7. jp_common.add(jl) ;
8. Font font = new Font("华文彩云",Font.BOLD,30) ;
9. jl.setFont(font) ;
10. }
问题:
2、一旦我把commonClass()中jp_common.add(jl) ;这一句放在函数的最下面,则“Welcome!”就不能显示 华文彩云 这种字体!为什么?
2. JPanel jp_container = new JPanel(){
3. public void setBackground(Color bg) {
4. super.setBackground(Color.BLUE);
5. }
6. public Component add(Component comp) {
7. JLabel jl = new JLabel("你好!") ;
8. return super.add(jl);
9. }
10. } ;
11. add(jp_container) ;
12. }
13. public void commonClass(){
14. JPanel jp_common = new JPanel();
15. jp_common.setBackground(Color.red) ;
16. add(jp_common) ;
17.
18. JLabel jl = new JLabel("Welcome!") ;
19. jp_common.add(jl) ;
20. }结果,containerClass(){}不显示【你好!】两个字,问题:
1、containerClass(){}不显示【你好!】两个字,即使把JLabel jl放在内部类的最外面也不行!为什么?怎么改?2、commonClass(){}中,我重新写了些,大家看下:1. public void commonClass(){
2. JPanel jp_common = new JPanel();
3. jp_common.setBackground(Color.red) ;
4. add(jp_common) ;
5.
6. JLabel jl = new JLabel("Welcome!") ;
7. jp_common.add(jl) ;
8. Font font = new Font("华文彩云",Font.BOLD,30) ;
9. jl.setFont(font) ;
10. }
问题:
2、一旦我把commonClass()中jp_common.add(jl) ;这一句放在函数的最下面,则“Welcome!”就不能显示 华文彩云 这种字体!为什么?
第一个问题中:add(Component comp);你可以放条输出语句进去测试一下第二个问题:是还没有刷新,再加个 jl.repaint();就可以了
第一个问题中:add(Component comp)并没有执行;你可以放条输出语句进去测试一下第二个问题:是还没有刷新,再加个 jl.repaint();就可以了
我第一个问题还是没解决,第二个问题,我自己这样做也可以: public Component add(Component comp) {
JLabel jl = new JLabel("你好!") ;
return super.add(jl);
}此时,就可以了!但是,第一点该怎么做呢?求教!
package Example_1;import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
public class TestContainerClassContrastCommonObject extends JFrame {
private static final long serialVersionUID = 1L;
int width = 500 ;
int height = 200 ;
public void setupWindow(){
setVisible(true);
setMinimumSize(new Dimension(width,height)) ;
setLocationRelativeTo(null) ;
setLayout(new GridLayout(2,1)) ;//我设置为网格布局
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent arg0) {
System.exit(0) ;
super.windowClosing(arg0);
}
}) ;
}
public void containerClass(){
JPanel jp_container = new JPanel(){
private static final long serialVersionUID = 1L;
public void setBackground(Color bg) {
super.setBackground(Color.BLUE);
}
public Component add(Component arg0) {
return super.add(new JLabel("你好!"));
}
} ;
add(jp_container) ;
// JPasswordField jpf = new JPasswordField(5) ;
// jp_container.add(jpf) ;
}
public TestContainerClassContrastCommonObject() {
setupWindow() ;
containerClass() ;
pack() ;
}
public static void main(String[] args) {
new TestContainerClassContrastCommonObject() ;
}
}
之后,把 注释 掉的部分取消掉注释,就有了JLabel("你好")。
我有怪了,那个之前jp_container内部写add()就没有出现,但是我又放一个add(JPasswordField)在精JPanel 里,他不出现JPasswordField,反而出现JLabel,怪了,为什么呢?
JPasswordField jpf = new JPasswordField(5);
jp_container.add(jpf);时就调用了你重写的add函数所以“你好”出现了,而你之后在panel中调用add(JPasswordField),相当于调用了你重写的add函数,所以jabel出现了。而你的add(jpf)无效就是因为你重写add函数覆盖原来的add函数!
我可不可以这样讲:JPanel jp = new JPanel(){...},这里跟一个大括号,括号里的东西时重写?
假设是吧,但是,如果没有那句add(),我一直认为JPanel jp = new JPanel(){...}在new的时候就已经初始化并且调用了{...}大括号里的东西,不然的话,为什么我写一句jFrame.add(jp),就显示出jp的背景颜色【假设JPanel jp = new JPanel(){public void setBackground(){...super.(red)}}】。望指明我上面这几句话的错误之处,我一直在犯糊涂!
大括号里的函数是重写了,但不一定会被调用,而你的、setBackground()执行了是由于有其他函数调用了它,add函数没有被调用!你可以写个简单的例子试一下:创建一个新类继承JPanel并在类中重写setBackground(),在测试一下该类你会发现setBackground()被自动调用,原因如上面说的,setBackground被其他函数调用了。再说一个例子为什么有些函数会被调用了在学习java的画图功能时候,经常会看到super.paintComponent,书上说一定要有而且必须是在第一句,不然就会出问题!可恨的是书上没有解析这是为什么。下面简单的解析一下这个语句的作用。
首先我们要知道GUI组件(如JPanel,JButton等)本身并没有paintComponent的方法,它的paintComponent是JComponent继承下来的。
然后我们来看看JComponent的paintComponent
protected void paintComponent(Graphics g) {
if (ui != null) {
Graphics scratchGraphics = SwingGraphics.createSwingGraphics(g);
try {
ui.update(scratchGraphics, this);
}
finally {
scratchGraphics.dispose();
}
}
}
createSwingGraphics的有什么用呢? 只是用于创建一个新的画图对象而与
public static Graphics createSwingGraphics(Graphics g) {
if (g == null) {
Thread.dumpStack();
return null;
}
return g.create();
}
那update呢? 明显是用于画出组件的背景色
public void update(Graphics g, JComponent c) {
if (c.isOpaque()) {
g.setColor(c.getBackground());
g.fillRect(0, 0, c.getWidth(),c.getHeight());
}
paint(g, c);
}
最后就用dispose把画图的对象占用的资源释放掉!
综合以上,我们发现paintComponenet的作用是给组件画上背景色。如果不调用此方法,我们之前对组件设置的背景色等属性将不会被展现。如果此方法在子类的实现中最先被调用,背景就处于最底下的一层,子类其他利用g进行的绘图将在有一个背景的基础下进行。
假设有一个JComponent JComponent_Name = new JComponent{...Method...}
我来根据这个JComponent来做些思考,劳烦你指点下:1、根据你所述:在JComponent JComponent_Name = new JComponent{...Method...}中,Method只是重写被new 的JComponent 的方法,而之所以能运行,是因为【隐藏的方法】将其调用了,而未被调用的,则不被运行!请问这句话我分析的正确不?2、突然想起你之前说我很多方法之所以不被显示,需要repaint(),也就是说,只要repaint(),就可以调度所有new 里面的 被重写的 Method ?3、我自己直接在new {...}里面重写repaint(),没反应!拿到外面写也没反应,作为初学者,我渴望你能否写个(或说修改下)某个用了repaint的方法我看看?如果能,请看下文: 我自己写了个监听,目的是解决JPasswordField中setText()的文字不能显示的问题,我是这样想的,同时放JTextField(JTF)和JPasswordField(JPF)在JPanel中,先jpanel.add(JTF),等到MouseListener监听到有鼠标移动到jpanel,再隐藏JTF,然后再jpanel.add(JPF),为了不影响代码,于是,我做了个实验。这个实验,是在监听器里写一个add(JComponent),看看有没有用!但让我惊讶的是,我发现,没有用,我思考了很久,突然发现,我点击放大或缩小窗口,这JComponent就出现了,我马上想到你上次所说的repaint(),可惜,我不会用!望指点【我把我写的实验代码贴出来供你修改】:package Example_1;
import java.awt.BorderLayout;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;public class TestContainerClassContrastCommonObject extends JFrame {
private static final long serialVersionUID = 1L;
TestContainerClassContrastCommonObject(){
JTextField jl_1 = new JTextField("点我,我是老大!") ;
final JLabel jl_2 = new JLabel("点我,我是老二!") ;
getContentPane().add(jl_1,BorderLayout.SOUTH) ;
jl_1.addFocusListener(new FocusListener(){
public void focusGained(FocusEvent arg0) {
getContentPane().add(jl_2,BorderLayout.CENTER);
repaint();
}
public void focusLost(FocusEvent arg0) {
}
}) ;
this.setBounds(50, 50, 300, 300);
this.setVisible(true) ;
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE) ;
}
public static void main(String[] args) {
new TestContainerClassContrastCommonObject() ;
}
}
函数重写了,但不一定被调用就是这个意思,而repaint是重画的意思,不是可以调度所有new 里面的 被重写的 Method ,这个完全两码事。如你最初问的那个关于字体的问题,repaint就是重新画图的意思,那么我们才能看到最新的!问题总是问不完了,建议你先看java的基础书籍,掌握基本后再去看进阶!
我听了这么久的理论,可找不到一个实例!希望你直接修改下我的{点我,我是老大,点我,我是老二}这个用了FocusListener的代码。我想看看实例,这样思考就不会空泛了,而是具体了!谢谢
你写的FocusListener中的repaint没有起到具体作用,因为一开始你的输入框就已经获得焦点调用你函数内的代码,举个简单的例子,你为输入框添加个鼠标点击事件,然后在里面写:removeall();
//repaint();如果没有repaint()将看不到界面重画,有repaint()则看到界面中的控件全部没了好吧,记得结贴哦亲!
好的!
我先看下你提供的removeall的用法!