0

2 つの問題のあるクラスで問題が発生しました。1 つは物を描画するためのもので、もう 1 つは以前に描画されたオブジェクトにパンとズームを実装するためのものです。

私のインターフェースが、空 (上部) とスライダー (ボット) を持つ 2 つのパネルのみであると想像してください。

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);
}

トップパネルは、グラフィックスを描画するために作成された render クラスを使用します。単純化:

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;
}
}

そして、私に問題を引き起こしている3番目のクラスは、スライダーをリッスンし、それに応じて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;
}
}

getLabel メソッドによって正常に返された JLabel を使用できないのはなぜですか?

4

1 に答える 1

2

クラスRenderのコンストラクターのenvContainerのローカルバージョンは、クラスインスタンス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);
  ...
}
于 2013-06-29T00:58:13.680 に答える