[英]Is it possible to paint a JComponent and all its children to another component?
I have an extended JPanel
class called GridPanel
. 我有一个扩展的
JPanel
类,称为GridPanel
。 It lets you drag and drop images into it from a JList
. 它使您可以将图像从
JList
拖放到其中。 The GridPanel
lets you drag the images around with the mouse and rearrange them as you want. GridPanel
允许您用鼠标拖动图像并根据需要重新排列图像。 What I'm interested in is making a thumbnail view of the GridPanel
component. 我感兴趣的是制作
GridPanel
组件的缩略图。
If I understand correctly, setting a JScrollPane
's view to be GridPanel
makes GridPanel
a child of a JViewPort
, which becomes a child of the JScrollPane
. 如果我理解正确,将
JScrollPane
的视图设置为GridPanel
会使GridPanel
成为GridPanel
的子JViewPort
,而JViewPort
成为JScrollPane
的子级。 Currently GridPanel
is already set to be the view of a JScrollPane
and I'm pretty sure GridPanel
can't have two parents. 当前,
GridPanel
已经设置为JScrollPane
的视图,我很确定GridPanel
不能有两个父级。 So I can't have two components share the same view, but I really only need the thumbnail view to paint a scaled visual copy of GridPanel
. 因此,我不能让两个组件共享同一视图,但实际上我只需要缩略图视图即可绘制
GridPanel
的缩放可视副本。
This leads to my question. 这引出了我的问题。 Is it possible to copy what
GridPanel
paints, but paint it on a completely separate component? 是否可以复制
GridPanel
绘制的内容,但将其绘制在完全独立的组件上?
This is an example of what I've tried, in case I'm not being understood. 这是我尝试过的示例,以防万一我不被理解。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class TestMain {
public static void main(String[] a) {
Color[] colors = new Color[]{Color.green, Color.red, Color.blue, Color.yellow};
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel content = new JPanel();
frame.setContentPane(content);
content.setLayout(new FlowLayout());
//using variable names to try and help relate to my question
final JPanel gridPanel = new JPanel();
gridPanel.setPreferredSize(new Dimension(200,200));
gridPanel.setLayout(new GridLayout(2, 2));
JLabel label;
for (Color c: colors){
label = new JLabel();
label.setOpaque(true);
label.setBackground(c);
gridPanel.add(label);
}
JScrollPane gridScroll = new JScrollPane(gridPanel);
final JScrollPane thumbnailScroll = new JScrollPane();
thumbnailScroll.setPreferredSize(new Dimension(200,200));
JButton tryThumbnailView = new JButton("Activate Thumbnail");
tryThumbnailView.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
thumbnailScroll.setViewportView(gridPanel);
frame.repaint();
}
});
content.add(tryThumbnailView);
content.add(gridScroll);
content.add(thumbnailScroll);
frame.pack();
frame.setVisible(true);
}
}
What I would like to have happen is for both components to show the same set of colored JLabels
, without duplicating those JLabels
. 我希望发生的事情是两个组件都显示同一组彩色的
JLabels
,而不必重复这些JLabels
。
All you have to do is "get rendering result" of one component and reuse it. 您要做的就是“获取一个组件的渲染结果”并重新使用它。 That takes:
这需要:
First three steps can be done like this: 前三个步骤可以这样完成:
@Override
public void paint(Graphics originalGraphics) {
GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsConfiguration c = e.getDefaultScreenDevice().getDefaultConfiguration();
//create own image to paint to
BufferedImage image = c.createCompatibleImage(getWidth(), getHeight());
Graphics2D reusableGraphics = image.createGraphics();
//let it paint into our graphics
super.paint(reusableGraphics);
// draw image on this component
originalGraphics.drawImage(image, 0, 0, null);
// draw image on other component
otherComponent.setMirrorImage(image);
}
In otherComponent you have to save image and paint it when required: 在otherComponent中,您必须保存图像并在需要时绘制它:
@Override
public void paint(Graphics g) {
if (mirroredImage == null) {
super.paintAll(g);
} else {
g.drawImage(mirroredImage, 0, 0, getWidth() * 3 / 4, getHeight() * 3 / 4, null);
}
}
public void setMirrorImage(BufferedImage mirroredImage) {
this.mirroredImage = mirroredImage;
repaint();
}
You can override paintComponent
like this: 您可以像这样重写
paintComponent
:
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.scale(scaleFactor, scaleFactor);
gridPanel.paintComponenet(g);
}
This assumes that gridPanel
either overrides paintComponent
as public
or this class has to be in the same package as GridPanel
. 假定
gridPanel
作为public
重写paintComponent
,或者此类必须与GridPanel
同一包中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.