2013-06-28 6 views
0

У меня проблема с двумя классами проблематики. Один для рисования вещей и другой для реализации панорамирования и масштабирования на ранее нарисованные объекты.JLabel неприменим к другим классам

Представьте свой интерфейс, как только две сплюнул панели, один пустой (вверху) и один с ползунком (СЭП):

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?

+0

Что вы имеете в виду, когда говорите, что не можете использовать его? Вы получаете сообщение об ошибке? – MaxAlexander

+0

что такое исключение во время выполнения? трассировки стека? – nachokk

+0

http://pastebin.com/TPSMax08 Интерфейс - это первый класс, а PanAndZoom - последний. – SOMN

ответ

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); 
    ... 
} 
+0

Чувак, ты потрясающий! : D – SOMN