我界面两个方法加载图像,label add()和g.drawimage
其中 gdrawimage中的图像需要按钮触发更换,label不需要....
问题: 是当我切换页面是,label和按钮变成白色无法复原.....空点按钮还能恢复...label里的图像只能最小化打开才能恢复,两部分代码如下 :label: ImageIcon imgNorth=new ImageIcon("north.jpg");
JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER);
jPanelNorth.add(labelNorth,null);
jContentPanel.add(jPanelNorth, BorderLayout.NORTH); drawimage 部分:
public void paint (Graphics g)
{
// super.paintComponent(g);
// if (img[index] == null ) return;
index=(index)%10;
g.drawImage(img[index], 0, 0, this);
repaint();
}
public void playClick()
{
index++; }其中这个问题 是加入 repaint语句 导致的,之前没有!!
其中 gdrawimage中的图像需要按钮触发更换,label不需要....
问题: 是当我切换页面是,label和按钮变成白色无法复原.....空点按钮还能恢复...label里的图像只能最小化打开才能恢复,两部分代码如下 :label: ImageIcon imgNorth=new ImageIcon("north.jpg");
JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER);
jPanelNorth.add(labelNorth,null);
jContentPanel.add(jPanelNorth, BorderLayout.NORTH); drawimage 部分:
public void paint (Graphics g)
{
// super.paintComponent(g);
// if (img[index] == null ) return;
index=(index)%10;
g.drawImage(img[index], 0, 0, this);
repaint();
}
public void playClick()
{
index++; }其中这个问题 是加入 repaint语句 导致的,之前没有!!
paintComponent再提一下 给你看个蚂蚁的腿 你知道是公是母吗?
{
// super.paintComponent(g);
看到我注释了没有,paintComponet早就用过了,不行啊,我知道他的作用是重绘每个组件,可问题是我旁边labelNorth 是 把图像添加进去的,我就想知道激活label里面图片的方法,原代码太啰嗦 ,我怕你们会没兴趣,好吧,贴出来吧~~public void init()
{this.setSize(166,230);
this.setContentPane(getJContentPanel());
}
private javax.swing.JPanel getJContentPanel()
{
Color playColor = new Color (100,100,100);
Font playFont = new Font ("default",Font.BOLD,10);
if(jContentPanel == null )
{
jContentPanel = new javax.swing.JPanel();
jContentPanel.setLayout(new BorderLayout());
jContentPanel.setBackground(java.awt.Color.WHITE);
if(jPanelNorth == null )
{
javax.swing.JPanel jPanelNorth = new javax.swing.JPanel(new GridLayout(1,0,0,0));
ImageIcon imgNorth=new ImageIcon("north.jpg");
if(labelNorth == null)
{
JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER);
jPanelNorth.add(labelNorth,null);
}
jContentPanel.add(jPanelNorth, BorderLayout.NORTH);
}if(jPanelSouth == null )
{
javax.swing.JPanel jPanelSouth = new javax.swing.JPanel(new GridLayout(2,0,0,0));
Icon imgSouth=new ImageIcon("south.jpg");
if (labelSouth == null)
{
JLabel labelSouth=new JLabel(imgSouth,JLabel.CENTER);
jPanelSouth.add(labelSouth,null);
if(jPanelPlay == null)
{
javax.swing.JPanel jPanelPlay = new javax.swing.JPanel (new GridLayout(1,1,0,0)) ;
// jPanelPlay.setLayout(null);
jPanelPlay.add(playButton = new MyJButton("PLAY",playColor,playFont ),null);
jPanelPlay.add(playButton = new MyJButton("STOP",playColor,playFont ),null);
jPanelSouth.add(jPanelPlay ,null);
}
// jPanelSouth.add(playButton = new MyJButton("play",playColor,playFont ),null);
}
jContentPanel.add(jPanelSouth, BorderLayout.SOUTH);
if(jPanelCenter == null )
{
JCenterPanel jPanelCenter = new JCenterPanel();
jContentPanel.add(jPanelCenter, BorderLayout.CENTER);
}
}
return jContentPanel;
}
public class JCenterPanel extends JPanel
{
Image[] img = new Image [10];
public JCenterPanel ()
{
try
{
for (int i=0; i<10; i++)
{
img [i] = getImage(getCodeBase(),(i+1)+".jpg" );
}
}
catch (Exception e)
{e.printStackTrace(); }
}
public void paint (Graphics g)
{
// super.paintComponent(g);
// if (img[index] == null ) return;
index=(index)%10;
g.drawImage(img[index], 0, 0, this);
repaint();
}
public void playClick()
{
index++;
} public void stopClick()
{
index=0;
}
}public class MyJButton extends JButton
{
Timer mouseTimer = null ;
public MyJButton( String pTitle, Color pBk, java.awt.Font pFont)
{
this.setText(pTitle);
this.setBackground(pBk);
this.setFont(pFont);
this.addMouseListener
(
new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount()==1)
{
mouseTimer = new javax.swing.Timer
(350,
new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (!Selected)
return;
if (getText().equals("PLAY"))
{
JCenterPanel jCenterPanel = new JCenterPanel();
jCenterPanel.playClick();
setBackground(java.awt.Color.GREEN);
mouseTimer.stop();}
else if (getText().equals("STOP"))
{
JCenterPanel jCenterPanel = new JCenterPanel();
jCenterPanel.stopClick();
setBackground(java.awt.Color.RED);
mouseTimer.stop();
}
}
}
);
mouseTimer.restart();
}
super.paintComponent(g);可以不用注释掉然后后面你说的很对,就是repaint的问题
这个方法很讨厌,他的名字非常的迷惑
实际上这个方法是很危险的,因为他有一个没有参数的repaint这个方法官方文档有解释
Components that render complex output should invoke repaint() with arguments defining only the region that requires updating. A common mistake is to always invoke the no-arg version, which causes a repaint of the entire component, often resulting in unnecessary paint processing.
翻译为
如果部件要呈现复杂的图形,就应该使用带参数的repaint()方法,通过参数来指定需要更新的区域。一个比较常见的错误是总是调用无参数的repaint()来提出重画请求,这个方法会重画整个部件,经常导致一些不必要的画图处理。而我个人对最后一句有疑问
看过源码之后,我认为是因为无参数的repaint仅仅是调用了parent容器的repaint
但是这个repaint是没有对当前的组件进行绘画处理的
所以导致最后什么都看不见希望有所帮助
建议:这里用update(g),应该就可以了
如 public void paint (Graphics g)
{ super.paintComponent(g);
index=(index)%10;
g.drawImage(img[index], 0, 0, this);
update(g);
repaint(30,0,0,120,120);
// update(g);
} 可是这样连初始化都失败了~~~~经查阅资料发现,update更新组件是在重量级组件时才会被调用,而我这边的JPanel类显然是轻量级,repaint会直接调用paint,况且repaint包含了update方法,如下:
repaint(Graphics g) {
g.clearRect(0,0,width,height);
update(g);
}
所以加不加update都无法解决.....
另外我想重申,我的问题集中在窗口被覆盖后激活的重绘,paint方法实现drawimage区域我想利用 repaint实现动画,但是这显然影响了
ImageIcon imgNorth=new ImageIcon("north.jpg");
JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER);
JLabel中的 图片在窗口被覆盖,然后激活时的重绘,这样导致周围是白色的结果,我的焦点在于有没有类似repaint的方法在 窗口激活时让 旁边的label中的图片再重新加载一遍???
还有repaint(30,0,0,120,120);不行吗?
还有repaint(30,0,0,120,120);不行吗?我是做得按钮实时触发的repaint,drawimage里面的图片
很奇怪,repaint放在此程序的paint{}以外任何地方都没有起到调用paint的作用(经过断点调试),唯独放在paint里面可行,代码如下:按钮触发:
new MouseAdapter(){
public void mouseClicked(MouseEvent e) {
if (e.getClickCount()==1) {
mouseTimer = new javax.swing.Timer(350, new ActionListener()
{public void actionPerformed(ActionEvent evt) { if (getText().equals("PLAY"))
{ JCenterPanel jCenterPanel = new JCenterPanel();
jCenterPanel.playClick();//接口调用 paint 方法
............public class JCenterPanel extends JPanel
{Image[] img = new Image [10];public JCenterPanel ()
{ try { for (int i=0; i<10; i++)
{img [i] = getImage(getCodeBase(),(i+1)+".jpg" );}
}
catch (Exception e)
{e.printStackTrace(); }}
public void paint (Graphics g)
{
super.paintComponent(g);
// if (img[index] == null ) return;
index=(index)%10;
g.drawImage(img[index], 0, 0, this);
repaint(30,0,0,120,120); }
public void playClick()
{index++; //repaint(30,0,0,120,120); 放在这里无法响应按钮,放在paint函数里做到了,但带来如题的问题}
发来吧邮件已经发送,请查收~~~~~~~
没有,开始把repaint();放在playClick里面也不能调用paint,但是放在paint里面中间的画布居然可以响应 按钮,我怀疑程序是不是在按button时自动调用了paint,同时repaint()也能实现(完全是猜测,望达人解疑),但效果 出来了~~~
已经发了,请查收~~~把libel发在另外一个panel里不太理解意图,不过单纯修改label不太可能,这个位置都是按照需求摆放的....
(repaint产生事件 会导致面板调用paintComponent 和 paint 而调用paint 又重新repaint)
所以就想看看完整的代码
果然如此
button点击以后 将index++ 在paint的时候就会达到切换图片的效果
你所说的label 变白 不能刷新
估计是LZ的CPU太差了 死循环以后 所以就刷新不出来了
规格 Intel(R) Core(TM)2 CPU T5600 @ 1.83GHz
显示卡 NVIDIA GeForce Go 7300
内存 1047792 KB这配置也不算太差吧,那既然方法找到了能不能有更好的方法去repaint呢?
能不能避免这个死循环,只让他调用一次达到换图效果就行了啊~你有没有发现repaint在别的地方调用不了呢,比如在playclick 里面~~~
你那里写repaint肯定不行
cpu都是满的
之所以还能够显示图片是另外的线程还没有完全饿死不知道为什么你会显示出白色的东西,有可能是浏览器响应不了
因为我的浏览器不能显示applet,所以我这里改成JFrame了我的建议是
把这一句
jCenterPanel.paint(WebPlayer.this.getGraphics());
加到
jCenterPanel.playClick(); //接口的调用
这一句的后面,然后前面的repaint方法去掉还有
JCenterPanel jCenterPanel = new JCenterPanel();
变成
final JCenterPanel jCenterPanel = new JCenterPanel();
写在
if (e.getClickCount() == 1) {
的前面总之,我觉得代码看起来不是很舒服,还有很多可以改进的地方,楼主自己想吧
加油~~
不知道还会不会变白?
jCenterPanel.paint(WebPlayer.this.getGraphics());
加到
jCenterPanel.playClick(); //接口的调用
却没成功,我思考了一下,可能是因为 getGraphics()把下个图像的索引返回给了g,但同时index的数字也加1 ,就是说g和index值都变了....这样同样导致了下一次paint的Bug,况且好像paint函数仍然没有调用,因为没按Button的同时没有变化.....
还有这个语句插在这个位置也不妥,因为gui的语句放在一起最好,click时只要调用就好了,
另外,final JCenterPanel jCenterPanel = new JCenterPanel();我知道将变量变成不能被继承的最小单位,但我不清楚这样做的好处,请指明~还有你说到有很多可以改进的地方,简直是在吊我的胃口,迫切希望和你多交流~~~~
qq 781212997 msn [email protected]
你代码里面所谓的接口的东西 都是用错的 还有你的OO思想要培养一下 改一下你的代码
playclick 调用 WebPlayer的addIndex方法 来达到Index++的效果
在addIndex方法中添加对 图片切换面板的repaint
public class WebPlayer extends JApplet
{
private static final long serialVersionUID = 345678L; private javax.swing.JPanel jContentPanel = null;
private javax.swing.JPanel jPanelNorth = null;
private javax.swing.JPanel jPanelSouth = null;
private javax.swing.JPanel jPanelEast = null;
private javax.swing.JPanel jPanelWest = null;
private javax.swing.JPanel jPanelCenter = null;
private javax.swing.JPanel jPanelPlay = null; private javax.swing.JLabel labelNorth = null;
private javax.swing.JLabel labelSouth = null;
private javax.swing.JLabel labelEast = null;
private javax.swing.JLabel labelWest = null;
// private javax.swing.JLabel labelCenter = null ; private MyJButton playButton = null;
private boolean Selected = true;
// int i = 1;
int index = 0; public void init()
{
this.setContentPane(getJContentPanel());
this.setSize(166, 230); } public void start()
{ } private javax.swing.JPanel getJContentPanel()
{ Color playColor = new Color(100, 100, 100);
Font playFont = new Font("default", Font.BOLD, 10); if (jContentPanel == null)
{
jContentPanel = new javax.swing.JPanel(); jContentPanel.setLayout(new BorderLayout()); jContentPanel.setBackground(java.awt.Color.WHITE); // 将applet的总范围设置为broderlayout,构成播放器的大体结构 if (jPanelNorth == null)
{ javax.swing.JPanel jPanelNorth = new javax.swing.JPanel(
new GridLayout(1, 0, 0, 0)); ImageIcon imgNorth = new ImageIcon("north.jpg"); if (labelNorth == null)
{
JLabel labelNorth = new JLabel(imgNorth, JLabel.CENTER); // 在label里面加入图片 jPanelNorth.add(labelNorth, null);// 将有图片的label放进上部分的jpanel }
jContentPanel.add(jPanelNorth, BorderLayout.NORTH); // 上部分的jpanel放入整个borderlayout布局中 } if (jPanelSouth == null)
{
javax.swing.JPanel jPanelSouth = new javax.swing.JPanel(
new GridLayout(2, 0, 0, 0));// 将加入borderlayout.south的jpanel分成两列
Icon imgSouth = new ImageIcon("south.jpg");
if (labelSouth == null)
{
JLabel labelSouth = new JLabel(imgSouth, JLabel.CENTER);
jPanelSouth.add(labelSouth, null);// 将带标签的图像放入第一列 if (jPanelPlay == null)
{
javax.swing.JPanel jPanelPlay = new javax.swing.JPanel(
new GridLayout(1, 1, 0, 0));
// 将放入jpanelsouth第二列的jpanelplay分成两格,这里用
// gridlayout也很重要,避免了第一列的图像与其它模块产生缝隙 // jPanelPlay.setLayout(null); jPanelPlay.add(playButton = new MyJButton("PLAY",
playColor, playFont), null);
jPanelPlay.add(playButton = new MyJButton("STOP",
playColor, playFont), null); jPanelSouth.add(jPanelPlay, null);
} // jPanelSouth.add(playButton = new
// MyJButton("play",playColor,playFont ),null); }
jContentPanel.add(jPanelSouth, BorderLayout.SOUTH); } if (jPanelWest == null)
{
javax.swing.JPanel jPanelWest = new javax.swing.JPanel(
new GridLayout(1, 0, 0, 0)); Icon imgWest = new ImageIcon("west.jpg");
if (labelWest == null)
{
JLabel labelWest = new JLabel(imgWest, JLabel.LEFT);
jPanelWest.add(labelWest, null);
}
jContentPanel.add(jPanelWest, BorderLayout.WEST); } if (jPanelEast == null)
{
javax.swing.JPanel jPanelEast = new javax.swing.JPanel(
new GridLayout(1, 0, 0, 0));
Icon imgEast = new ImageIcon("east.jpg");
if (labelEast == null)
{
JLabel labelEast = new JLabel(imgEast, JLabel.RIGHT);
jPanelEast.add(labelEast, BorderLayout.NORTH); }
jContentPanel.add(jPanelEast, BorderLayout.EAST); } /*
* if(jPanelCenter == null ) {
*
* String image =new String(); switch (i) { case 1: image = "1.jpg";
* break; case 2: image = "2.jpg"; break; case 3: image = "3.jpg";
* break; case 4: image = "4.jpg"; break; case 5: image = "5.jpg";
* break; default: break; }
*
*
*
* javax.swing.JPanel jPanelCenter = new javax.swing.JPanel(); Icon
* imgCenter=new ImageIcon(image); if (labelCenter == null) { JLabel
* labelCenter=new JLabel(imgCenter,JLabel.CENTER);
* jPanelCenter.add(labelCenter,BorderLayout.CENTER);
*
*
*
* } jContentPanel.add(jPanelCenter, BorderLayout.CENTER);
*
* }
*/ if (jPanelCenter == null)
{
jPanelCenter = new JCenterPanel();// 这个体现了接口的作用,先实例化一个对应类的变量
jContentPanel.add(jPanelCenter, BorderLayout.CENTER);// 调用drawimage的主动画界面
} }
return jContentPanel; } //addIndex methond
public void addIndex()
{
index++;
System.out.println(index);
jPanelCenter.repaint();
}
//
public void cleanIndex()
{
index = 0;
jPanelCenter.repaint();
}
===============================
太长 分段回复
===================
接上
===================== // 主要的面板布局实现
public class JCenterPanel extends JPanel
{ Image[] img = new Image[10]; public JCenterPanel()
{ try
{
for (int i = 0; i < 10; i++)
{
img[i] = getImage(getCodeBase(), (i + 1) + ".jpg");
} }
catch (Exception e)
{
e.printStackTrace();
}
} public void paintComponent(Graphics g)
{
super.paintComponent(g);
// if (img[index] == null ) return; index = (index) % 10;
g.drawImage(img[index], 0, 0, this); } public void playClick()
{ addIndex(); } public void stopClick()
{
cleanIndex(); } } // 实现中间的动画转换 public class MyJButton extends JButton
{ Timer mouseTimer = null; public MyJButton(String pTitle, Color pBk, java.awt.Font pFont)
{ this.setText(pTitle);
this.setBackground(pBk);
this.setFont(pFont);
this.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (e.getClickCount() == 1)
{
mouseTimer = new javax.swing.Timer(350,
new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (!Selected)
return;
if (getText().equals("PLAY"))
{
JCenterPanel jCenterPanel = new JCenterPanel();
jCenterPanel.playClick();// 接口的调用
setBackground(java.awt.Color.GREEN); mouseTimer.stop();
}
else if (getText().equals("STOP"))
{
JCenterPanel jCenterPanel = new JCenterPanel();
jCenterPanel.stopClick();
setBackground(java.awt.Color.RED); mouseTimer.stop(); } }
});
mouseTimer.start();
}
else if (e.getClickCount() == 2 && mouseTimer.isRunning())
{
mouseTimer.stop();
setBackground(java.awt.Color.blue);
} }
}); } }
}
昨天在我这边是跑成功了才回复你的
虽然可能存在很多bug但是应该是满足下面的要求:
启动之后显示1.jpg
按下play之后不停播放图片
(但是stop之后没有停,因为你没有实现)
最小化后无显示问题
按下play之后,play变绿
需要注意的是按下play之后需要等一下图片才会切换
这样是很方便的
我开始也奇怪为什么你每次要新申明一个JCenterPanel
我只是把他改到了匿名内外,这样作用域小些
不过没想到不满足你的要求~~
说实话我并不知道你具体的布局是怎样的,所以就照上面的给你了:)