JLabel无法从其他类中使用

时间:2013-06-28 23:30:36

标签: java swing jlabel image-resizing

我遇到了两个问题类的问题。一个用于绘制内容,另一个用于实现平移和缩放到先前绘制的对象上。

想象一下,我的界面只有两个spitted面板,一个是空的(顶部),另一个是滑块(bot):

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import java.awt.BorderLayout;
import javax.swing.JSplitPane;
import javax.swing.JPanel;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JSlider;
import java.awt.FlowLayout;

public class Interface {
private JFrame mainFrame;
public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {Interface window = new Interface();window.mainFrame.setVisible(true);
            } catch (Exception e) { e.printStackTrace();}
   }
  });
}
public Interface() {initialize();}
private void initialize() {
  mainFrame = new JFrame();
  mainFrame.setTitle("LXView");
  mainFrame.setMinimumSize(new Dimension(800, 600));
  mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  mainFrame.setExtendedState(mainFrame.getExtendedState()| JFrame.MAXIMIZED_BOTH);
  mainFrame.getContentPane().setBackground(Color.WHITE);
  mainFrame.getContentPane().setLayout(new BorderLayout(0, 0));
  JSplitPane splitPane = new JSplitPane();
  splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
  splitPane.setOneTouchExpandable(true);
  splitPane.setBackground(Color.WHITE);
  mainFrame.getContentPane().add(splitPane, BorderLayout.CENTER);
  splitPane.setResizeWeight(0.99);
  JScrollPane scrollPane = new JScrollPane();
  scrollPane.setEnabled(false);
  splitPane.setLeftComponent(scrollPane);
  Render topPane = new Render();
  scrollPane.setViewportView(topPane);
  topPane.setLayout(new BoxLayout(topPane, BoxLayout.X_AXIS));
  JPanel botPane = new JPanel();
  splitPane.setRightComponent(botPane);
  botPane.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
  JLabel zoomLevel = new JLabel("Zoom level:");
  botPane.add(zoomLevel);
  JSlider slider = new JSlider(JSlider.HORIZONTAL, 25, 100, 100);
  slider.setMajorTickSpacing(15);
  slider.setMinorTickSpacing(5);
  slider.setPaintTicks(true);
  slider.setPaintLabels(true);
  slider.setPreferredSize(new Dimension(600,40));
  botPane.add(slider);
  PanAndZoom zoomer=new PanAndZoom(topPane.getLabel());
  slider.addChangeListener(zoomer);
}

顶部面板使用渲染类来绘制图形。简化:

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Render extends JPanel {
JLabel envContainer;
Render() {
  super();
  ImageIcon imageIcon = new ImageIcon("/path/to/img1");
  JLabel envContainer = new JLabel(imageIcon);
  super.add(envContainer);
}
@Override
public void paint(Graphics g) {
  super.paint(g);
  /*Render stuff*/
}
public JLabel getLabel() {
  return envContainer;
}
}

第三节给我带来麻烦,听取滑块并根据它设置JLabel图标:

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class PanAndZoom implements ChangeListener {
private JLabel label;
private BufferedImage image;


public PanAndZoom(JLabel lab){
  this.label=lab;
  try {
   image = ImageIO.read(new File("/path/to/img1"));
  } catch (IOException e) {
   e.printStackTrace();
  }
  label.setIcon(new ImageIcon("/path/to/img2"));//To test another img. It gives runtime errors.
}
public void stateChanged(ChangeEvent e) {
  int value = ((JSlider) e.getSource()).getValue();
  double scale = value / 100.0;
  BufferedImage scaled = getScaledImage(scale); // It also gives runtime errors.
  System.out.println("Scale:"+scale+" Value:"+value);
  label.setIcon(new ImageIcon(scaled));
  label.revalidate();

}
private BufferedImage getScaledImage(double scale) {
  int w = (int) (scale * image.getWidth());
  int h = (int) (scale * image.getHeight());
  BufferedImage bi = new BufferedImage(w, h, image.getType());
  Graphics2D g2 = bi.createGraphics();
  g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC);
  AffineTransform at = AffineTransform.getScaleInstance(scale, scale);
  g2.drawRenderedImage(image, at);
  g2.dispose();
  return bi;
}
}

为什么我不能使用JLabel,如果getLabel方法成功返回了它?

1 个答案:

答案 0 :(得分:2)

你是类的envContainer的本地版本Render的构造函数正在重写类实例envContainer。

public class Render extends JPanel {
JLabel envContainer; //<---- class instance
Render() {
  super();
  ImageIcon imageIcon = new ImageIcon("/path/to/img1");
  JLabel envContainer = new JLabel(imageIcon); //<---- overriden by local instance, hence class instance remains null
  super.add(envContainer);
}

我的猜测是你不是故意把它变成本地版本,因为你没有在构造函数中使用它。对Render构造函数进行以下更改。

Render() {
  ..
  this.envContainer = new JLabel(imageIcon);
  ...
}