公爵.png ->
arrowToLeft.gif ->
arrowToRight.gif ->
我需要一个 UI,我想在 Swing 中描绘网络设备的图形表示。为此,我只是加载多个图像并将它们一一重叠以显示设备的当前状态。我必须支持缩放这个视图。缩放代码如下所示。
public class LayeredPaneTest{
private JLayeredPane layeredPane;
private JScrollPane scrollPane;
private static double MIN_ZOOM_VALUE = 0.60; // 1.0;
private static double MAX_ZOOM_VALUE = 2.0;
private static final int LAYER1 = 0;
private static final int LAYER2 = 1;
private static final int LAYER3 = 3;
private double scaleFactor = 1.0;
private JInternalFrame internalFrame =
new JInternalFrame("LayeredPaneTest",false, false, false, false);
public LayeredPaneTest(){
loadView();
}
public JInternalFrame getView(){
return internalFrame;
}
private void loadView(){
((javax.swing.plaf.basic.BasicInternalFrameUI)internalFrame.getUI())
.setNorthPane(null);
internalFrame.setBorder(null);
internalFrame.getContentPane().add(buildCenterPane());
internalFrame.setSize(new Dimension(200, 200));
internalFrame.setLocation(0, 0);
internalFrame.setResizable(false);
internalFrame.setVisible(true);
}
private JPanel buildCenterPane(){
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
layeredPane = new JLayeredPane();
Position shelfPosition = new Position(0,0,200,200);
setLayeredPaneSize(shelfPosition);
JLabel label = getImageLabel(getImage("duke.png"),
new Position(0,0,100,100));
layeredPane.add(label, Integer.valueOf(LAYER1));
label = getImageLabel(getImage("arrowToLeft.gif"),
new Position(100,100,50,50));
layeredPane.add(label, Integer.valueOf(LAYER2));
label = getImageLabel(getImage("arrowToRight.gif"),
new Position(50,50,50,50));
layeredPane.add(label, Integer.valueOf(LAYER3));
scrollPane = new JScrollPane(layeredPane);
panel.add(scrollPane, BorderLayout.CENTER);
panel.add(getSliderPane(), BorderLayout.SOUTH);
return panel;
}
private Image getImage(String key){
InputStream is = this.getClass().getResourceAsStream(key);
try {
return ImageIO.read(is);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private void setLayeredPaneSize(Position shelfPosition){
int width = (int)(shelfPosition.getWidth() * scaleFactor + 10);
int height = (int)(shelfPosition.getHeight() * scaleFactor + 10);
layeredPane.setPreferredSize(new Dimension(width,height));
}
public void zoom(double factor){
if (factor < MIN_ZOOM_VALUE)
factor = MIN_ZOOM_VALUE;
else if (factor > MAX_ZOOM_VALUE)
factor = MAX_ZOOM_VALUE;
scaleFactor = factor;
Position shelfPosition = new Position(0,0,200,200);
setLayeredPaneSize(shelfPosition);
scrollPane.getViewport().repaint();
scrollPane.repaint();
scrollPane.getViewport().revalidate();
scrollPane.revalidate();
}
private JLabel getImageLabel(Image image, Position position) {
position = position.moveInRatio(scaleFactor);
ImageLabel label = new ImageLabel(new ImageIcon(image), position);
label.setOpaque(false);
label.setBounds(position.getLeft(),
position.getTop(),position.getWidth(),position.getHeight());
return label;
}
private JPanel getSliderPane(){
JPanel outer = new JPanel();
outer.setLayout(new FlowLayout());
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
final JSlider slider = new JSlider((int) (MIN_ZOOM_VALUE * 100),
(int) (MAX_ZOOM_VALUE * 100), 100);
slider.setMajorTickSpacing(1);
slider.setMinorTickSpacing(1);
double sliderValue = scaleFactor * 100.0;
slider.setValue((int) sliderValue);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
scaleFactor = slider.getValue() / 100.0;
zoom(scaleFactor);
}
});
panel.add(slider, BorderLayout.CENTER);
outer.add(panel);
return outer;
}
public static void main(String...strings){
JFrame frame = new JFrame("FrameDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new LayeredPaneTest().getView(),
BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
static class Position{
private final int left,top,width,height;
Position(int x1, int y1, int x2, int y2){
this.left = x1;
this.top = y1;
this.width = x2;
this.height = y2;
}
public int getLeft() {
return left;
}
public int getTop() {
return top;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
private class ImageLabel extends JLabel{
private static final long serialVersionUID = 6152144095443433296L;
private ImageIcon image;
private Position position;
public ImageLabel(ImageIcon image, Position position){
super(image);
this.image = image;
this.position = position;
}
public void paintComponent(Graphics g) {
int newX = (int)(position.getLeft() * scaleFactor);
int newY = (int)(position.getTop() * scaleFactor);
Graphics2D g2 = (Graphics2D)g;
int newW = (int)(position.getWidth() * scaleFactor);
int newH = (int)(position.getHeight() * scaleFactor);
setBounds(newX, newY, newW, newH);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(image.getImage(), 0, 0, newW, newH, null);
}
}
}
但这里的问题是,当我放大一次并缩小时,一些图像会消失。知道为什么它会这样吗?
以下是重现该错误的步骤;一个。将滑块拖动到最大值,b。见证图像被扩展到最大并引入滚动条,c。现在图像的几个部分被隐藏了,d。现在将滑块拖动到最小。e. 图像的隐藏部分消失。