菜鸟问题:怎样实现键盘事件?(外一则)

liangfengxx 2004-12-15 06:06:06
才学swing,遇到2个问题,查资料未果,还望高手来解答一下,谢过先!

1.键盘事件监听的问题

一个登录窗口,输入用户名和密码后,一般是按“确定”按钮进行登录。但我想在输入完毕后按Enter键登录。我试过为“确定”按钮添加KeyListener,不过没有反应,这该怎么解决啊?

2.有关图形和swing控件的。

在400*300的窗口上用drawImage()方法画一张图片在窗体上:
image=Toolkit.getDefaultToolkit().getImage("About.gif");
g.drawImage(image,0,0,400,200,this);
从drawImage()的参数可以看出该图片并没有全部占满整个窗体。然后,我有添加一个按钮在图片的
下面:
JButton okButton=new JButton();
okButton.setText("确定");
okButton.setBounds(new Rectangle(160,240,80,30));
this.getContentPane().add(okButton);
但是运行的时候只显示图片。如果要显示按钮,需要在按钮所在的区域点一下,这个按钮才能显示出
来。为什么不能同时一起显示图片和按钮呢?

哪位高手能给我解决一下啊?不甚感激
...全文
204 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
liangfengxx 2004-12-17
  • 打赏
  • 举报
回复
晕了晕了,用上述方法,按钮是能显示了,但是图片又不能显示了!
我用JLabel加图片还没试,希望这样能行.
dirlove 2004-12-17
  • 打赏
  • 举报
回复
你要认清一点,按钮的外貌和图片没有本质区别,他们都是由paint(Graphics g)画出来的,所以按钮和图片完全可以放在一个JComponent里面。先画图片,然后把按钮画出来就是了。
你把按钮放到JLabel里面,治标不治本,反而会出现同样的问题,JLabel没有画出来。不过,你要是用BorderLayout布局,图放上面,按钮放下面,那就不是画图的问题了。

下面是我写的一个简单的程序,我用图片填充整个JPanel,然后把按钮放在JPanel上,这样按钮就好像镶嵌在图片上面一样,程序已经测试过,你参考一下吧。


import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Toolkit;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PaintPanel extends JPanel {
public PaintPanel() {

}

public void paint(Graphics g) {
Image image = Toolkit.getDefaultToolkit().getImage("image.jpg");
g.drawImage(image, 0, 0, 400, 300, this);

//把子组件全部画出来,包括button
super.paintComponents(g);
}

public static void main(String[] args) {
JButton button = new JButton("确定");
button.setBounds(new Rectangle(160, 200, 80, 30));

PaintPanel panel = new PaintPanel();
panel.setLayout(null);
panel.add(button);

JFrame frame = new JFrame();
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(panel, BorderLayout.CENTER);
frame.setBounds(300, 300, 400, 300);
frame.setVisible(true);
}
}
liangfengxx 2004-12-16
  • 打赏
  • 举报
回复
楼上两位说得非常有道理,我确实是用paint(Graphics g){...}画的图,然后在构造方法中添加按钮组件。
小弟我好生佩服,我去试一下先,回来结帖!
dirlove 2004-12-16
  • 打赏
  • 举报
回复
问题1:为用户名和密码的JTextField加KeyListener。因为键盘输入只触发焦点所在的组件上的KeyListener。所以当焦点不在JButton上时,按钮上的KeyListener是没有作用的。用户在输入时,焦点一定在用户名或密码的JTextField上,此时JTextField上的KeyListener才起作用。当然,你用"Tab"键把焦点切换到JButton上,你的按钮监听就有用了。
把功能代码写在KeyListener的keyPressed或keyReleased方法中,不要写到keyTyped里去了。
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
//TODO
}
}

问题2:首先我们一起想象一下,一个JComponent好像一个画布,paint方法就是画笔,执行一次g.drawImage就往画布上添上一笔色彩,当执行下一次g.drawImage时,如果这一笔和上一笔有重复的地方,就会覆盖掉上次画的。
你的问题是覆盖了超类的paint()方法后,你的paint()方法中只有画图的代码,没有画窗体的代码,这样窗体就没有画出来。当你点击按钮时,系统会自动调用按钮的paint()方法,所以按钮就画出来了。但是当最小化时,整个窗体会被刷新,这时系统调用你写的paint()方法,结果按钮又被覆盖掉了。
问题清楚了,解决的方法也就容易。

方法一:
public void paint(Graphics g){
image=Toolkit.getDefaultToolkit().getImage("About.gif");
g.drawImage(image,0,0,400,200,this);
//把button画出来
button.paint(g.create(button.getX(), button.getY(), button.getWidth(), button.getHeight()));
}

方法二:
public void paint(Graphics g){
image=Toolkit.getDefaultToolkit().getImage("About.gif");
g.drawImage(image,0,0,400,200,this);
//把窗体里的子组件全部画出来,包括button
super.paintComponents(g);
}

这样button还可以放到image上。其实还有其他的许多思路,比如按区域画,自己细细琢磨吧。
总之把握一点,后画的覆盖先画的。


ForestOcean 2004-12-16
  • 打赏
  • 举报
回复
关于问题2

思考...

发觉不知不觉被你的思路束缚住了。

想过再三,觉得这个问题是这样的(本人主观猜测):
每个容器都有自己的绘制方法,draw***()或paint***(),这些方法决定着这个容器的外观,你在一个容器的绘制方法内部绘制了一个图片,其实就决定了它的外观,而你所加入的按钮则被这个外观所覆盖,而你的按钮又拥有一个监听者,也就是说,在容器的按钮部分可以接受一些事件,当这些事件被触发后,由于容器没有被重画(调用repaint()方法),所以这个按钮就出现了。当发生一些如容器大小改变、容器所在的窗口最大化和最小化等情况下,容器调用其repaint()方法,这时,你的按钮则再度消失。

解决这个问题的办法其实很有意思,就是为图形创建一个容器,并将其放入父容器中,而不是调用父容器的paint或draw方法。如果我没有猜错,你问题二的的代码放在一个包含Graphics g为参数的绘制方法中。顺便提一下,这些代码应放入父容器的初始化中,而不是绘制方法中。

示意代码如下:

// add image
JLabel img = new JLabel(new ImageIcon("About.gif"));
img.setBounds(x, y, width, height);
this.getContentPane().add(img);
// add button
...
tomy_xu_1981 2004-12-16
  • 打赏
  • 举报
回复
说的不是很懂
御南 2004-12-16
  • 打赏
  • 举报
回复
可能是屏幕刷新的时候又会到了原来的状态了吧
liangfengxx 2004-12-16
  • 打赏
  • 举报
回复
怎么没人啊?
还有一个现象就是最小化之后再最大化也会出现同样的问题
liangfengxx 2004-12-15
  • 打赏
  • 举报
回复
好象不是很爽,继续思考.......
zhaohao19853 2004-12-15
  • 打赏
  • 举报
回复
你的第一个问题
点击按钮的不应该用KeyListener,应该用ActionListener
第二个问题
要不是布局管理器,要不就是加的层不对,一个面板是分很多层的,我也没有搞清楚,学习中~
tom2005 2004-12-15
  • 打赏
  • 举报
回复
关注
A拉伦 2004-12-15
  • 打赏
  • 举报
回复
一、你的对按钮加键盘监听是对的
但是你要判断当按键为Entry是促发你的确定按钮的Actionglistener 事件

二、
那时由于你的画虽然没有沾满这个窗体,但是你的画法是在整个窗体上画画,就是整个窗体只是作为一个花布被你使用了阿 ,而按钮被你的花布盖住了
你可以先在一个Panel上画画,接着在另一个panel上加按钮:
JPanel imagePanel=new JPanel();
JPanel btnPanel=new JPanel();
this.getContentPane().setLayout(new BorderLayout());
image=Toolkit.getDefaultToolkit().getImage("About.gif");
g.drawImage(image,0,0,400,200,imagePanel);
JButton okButton=new JButton();
okButton.setBounds(new Rectangle(160,240,80,30));
okButton.setText("确定");
btnPanel.add(okButton);
this.getContentPane().add(imagePanel, BorderLayout.Center);
this.getContentPane().add(btnPanel, BorderLayout.South);
这段代码没有测试!!但是就是这个意思啊!!
你修改一下就可以用了阿!!
ForestOcean 2004-12-15
  • 打赏
  • 举报
回复
关于问题2:
你用的是不是Applet?还是在重载paintComponent()方法?你应该考虑使用布局管理器,将两部分分开来管理。
classjava 2004-12-15
  • 打赏
  • 举报
回复
呵呵,还是怪怪的
关注中
御南 2004-12-15
  • 打赏
  • 举报
回复
1.不是对JButton添加键盘事件,而是对文本框添加键盘事件。也可以用setDefaultButton()方法试一下
2.这个问题我没搞懂的是:this.getContentPane().add(okButton)是把按钮添加到内容层,而drawImage()是把图片画到Frame的哪一层呢?
liangfengxx 2004-12-15
  • 打赏
  • 举报
回复
调用repaint();后还是不行啊,唯一的变化是鼠标不停地闪动!
ForestOcean 2004-12-15
  • 打赏
  • 举报
回复
一、
你需要为(J)TextField加入事件监听者,用户名和密码两个都需要,同时检测两个文字域。

二、
首先在this.getContentPane().add(okButton, 0);
可以的,调用一下
repaint();
方法即可。

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧