我有两个JInternalFrames,每个都包含一个JPanel。一个JPanel (源)更新它的图形用户界面和响应鼠标事件的一些数据。另一个JPanel (目标)接收指示数据已更改的事件并相应地更新其外观。
如果源面板与目标面板重叠,则目标面板中的重绘将触发源面板中的重绘。而且,即使对目标面板所需的更改被源面板遮住了,目标面板仍然重新绘制,并且仍然在源面板中触发重绘。
在我的实际应用程序中,这会造成性能问题,因为多个面板正在鼠标拖动上触发重新绘制,源面板有一个复杂的图像要显示。
如何防止目标面板更新触发源面板中的重新绘制?
我尝试过的事情:
package components;
import javax.swing.JInternalFrame;
/* Used by InternalFrameDemo.java. */
public class MyInternalFrame extends JInternalFrame {
static int openFrameCount = 0;
static final int xOffset = 30, yOffset = 30;
public MyInternalFrame() {
super("Document #" + (++openFrameCount),
true, //resizable
true, //closable
true, //maximizable
true);//iconifiable
setSize(300,300);
setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
}
}package components;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class SourcePanel extends JPanel {
int boxX, boxY;
int boxWidth = 10;
int boxHeight = 10;
public SourcePanel(DataModel data) {
addMouseListener(new MouseAdapter()
{
@Override
public void mousePressed(MouseEvent evt)
{
if (!SwingUtilities.isRightMouseButton(evt))
{
boxX = evt.getX();
boxY = evt.getY();
data.update(boxX,boxY);
repaint();
}
}
});
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
int x = Math.min(boxX, this.getWidth()-boxWidth);
int y = Math.min(boxY, this.getHeight()-boxHeight);
g.drawRect(x, y, boxWidth, boxHeight);
g.drawRect(x + 1, y + 1, boxWidth - 2, boxHeight - 2);
}
}package components;
import java.awt.Color;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JPanel;
public class TargetPanel extends JPanel implements PropertyChangeListener {
int boxX, boxY;
int boxWidth = 10;
int boxHeight = 10;
public TargetPanel(DataModel data) {
data.addPropertyChangeListener(this);
}
@Override
public void propertyChange(PropertyChangeEvent evt)
{
//draw something in response to the data change
boxX = ((int[])evt.getNewValue())[0];
boxY = ((int[])evt.getNewValue())[1];
repaint();
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
int x = Math.min(boxX, this.getWidth()-boxWidth);
int y = Math.min(boxY, this.getHeight()-boxHeight);
g.fillRect(x, y, boxWidth, boxHeight);
}
}package components;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
public class DataModel {
int datax = 10;
int datay = 10;
public DataModel()
{
}
public void update(int x, int y)
{
int[] olddata = new int[]{datax,datay};
datax = x;
datay = y;
int[] newdata = new int[]{datax,datay};
changeSupport.firePropertyChange("DataChange", olddata, newdata);
}
protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
public void addPropertyChangeListener(PropertyChangeListener listener)
{
changeSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener)
{
changeSupport.removePropertyChangeListener(listener);
}
}(原始JInternalFrame示例代码的版权通知:)
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ 发布于 2017-10-19 20:51:14
您可以缓存鼠标更改,并按间隔执行,或在鼠标跟踪结束时执行。
最简单的办法可能是尝试一次延期的重新油漆。
@Override
public void propertyChange(PropertyChangeEvent evt)
{
//draw something in response to the data change
boxX = ((int[])evt.getNewValue())[0];
boxY = ((int[])evt.getNewValue())[1];
repaint(200L);
}实际上,在几次调用repaint(200L);之后重新绘制。(就我的感觉而言,我已经选择了5秒的高价值。)
https://stackoverflow.com/questions/46836269
复制相似问题