繁体   English   中英

尝试在运行时更改JTextPane的背景,成功但出现错误

[英]Trying to change background of JTextPane during runtime, succeeding but with errors

因此,我有一个JTextPane对象,需要在运行时将其背景更改为特定图像的背景。 我所看到的似乎是错误的(用于更改背景并调用repaintBackground() JComboBox似乎在选择时不会自动repaintBackground() ,等等),它还会抛出一个null指针,而且我不知道为什么背景会发生变化。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.text.BoxView.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI$RootView.paint(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paintSafely(Unknown Source)
at javax.swing.plaf.basic.BasicTextUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthEditorPaneUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthEditorPaneUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
etc etc etc....

这是我的对象:

public class PreviewPane extends JTextPane  {
    private String _name = "bg3";   

    public PreviewPane() {
        super();
        setOpaque(false);
        StyledDocument document = this.getStyledDocument();
        SimpleAttributeSet center = new SimpleAttributeSet();
        StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
        document.setParagraphAttributes(0, document.getLength(), center, false);
    }

    @Override
    protected void paintComponent(Graphics g)  throws RuntimeException{
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());

        BufferedImage img = null;

            try {
                img = ImageIO.read(new File(getClass().getResource("/icons/"+_name+".png").toURI()));
            } catch (IOException | URISyntaxException e) {
                // TODO Auto-generated catch block
                //e.printStackTrace();
            }

         g.drawImage(img, 0, 0, this);


        super.paintComponent(g);
    }

    public void repaintBackground(String bgName){

        _name = bgName;

        paintComponent(this.getGraphics());

    }

}

任何帮助,将不胜感激。

  1. paintComponent(this.getGraphics()); - 您永远不必显式调用paintComponent 而是调用repaint()

  2. super.paintComponent(g); 应该在paintComponent方法的开始处或至少在使用Graphics上下文进行任何绘画之前调用。

  3. 不要在paintComponent方法中加载图像。 一种选择是将缓存保留在Map<String, Image> 这样,您可以轻松地引用它们,而不必在每次更改时都加载它们。 总的来说这是不是一个巨大的问题,你是否决定缓存与否。 您可以只在repaintBackground方法中加载它。

  4. 保持班级成员的Image image; 这将是您用来绘制的Image 您的repaintBackground ,我会让它接受一个Image而不是String。 Image传递将类的成员Image image被用于绘画。 如果您决定从该方法加载图像,则仍然可以让该方法接受String。

     classs MyPanel extends JPanel { Image image; public void repaintBackground(Image image) { this.image = image; repaint(); } protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image); } } 
  5. paintComponent不应抛出RuntimeException

这是一个完整的例子。 我决定使用Map缓存。 由您决定如何执行。 您可以通过多种方式来处理此问题。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class ImageChangeDemo {

    private ImagePanel imagePanel = new ImagePanel();

    public ImageChangeDemo() {
        JFrame frame = new JFrame();
        frame.add(imagePanel);
        frame.add(createCombo(), BorderLayout.PAGE_START);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private JComboBox createCombo() {
        String[] items = {
            ImagePanel.DIRECTORY,
            ImagePanel.COMPUTER,
            ImagePanel.FILE,
            ImagePanel.FLOPPY,
            ImagePanel.HARD_DRIVE
        };
        JComboBox comboBox = new JComboBox(items);
        comboBox.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                imagePanel.repaintBackground(comboBox.getSelectedItem().toString());
            }
        });
        return comboBox;
    }

    private class ImagePanel extends JPanel {
        public static final String DIRECTORY = "directory";
        public static final String FILE = "file";
        public static final String COMPUTER = "computer";
        public static final String HARD_DRIVE = "harddrive";
        public static final String FLOPPY = "floppy";

        Map<String, Image> images = new HashMap<>();

        private Image currentImage;

        public ImagePanel() {
            initImageMap();
            repaintBackground(DIRECTORY);
        }

        private void initImageMap() {
            ImageIcon dirIcon = (ImageIcon)UIManager.getIcon("FileView.directoryIcon");
            ImageIcon fileIcon =(ImageIcon)UIManager.getIcon("FileView.fileIcon");
            ImageIcon compIcon = (ImageIcon)UIManager.getIcon("FileView.computerIcon");
            ImageIcon hdIcon = (ImageIcon)UIManager.getIcon("FileView.hardDriveIcon");
            ImageIcon flopIcon = (ImageIcon)UIManager.getIcon("FileView.floppyDriveIcon");
            images.put(DIRECTORY, dirIcon.getImage());
            images.put(FILE, fileIcon.getImage());
            images.put(COMPUTER, compIcon.getImage());
            images.put(HARD_DRIVE, hdIcon.getImage());
            images.put(FLOPPY, flopIcon.getImage());
        }

        protected void repaintBackground(String key) {
            currentImage = images.get(key);
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(currentImage, 0, 0, getWidth(), getHeight(), this);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(150, 150);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
                new ImageChangeDemo();
            }
        });
    }
}

首先,分别对图像进行初始化和绘制。 将img加载移出油漆。 也不要尝试创建文件。 如果无法创建JAR文件中的图像。

public PreviewPane() {
    super();
    setOpaque(false);
    StyledDocument document = this.getStyledDocument();
    SimpleAttributeSet center = new SimpleAttributeSet();
    StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER);
    document.setParagraphAttributes(0, document.getLength(), center, false);
}

BufferedImage img = null;

private void initImg() {
    if( img==null) {
        img = ImageIO.read(getClass().getResourceAsStream("/icons/"+_name+".png")));
//process missing img here
    }
}

@Override
protected void paintComponent(Graphics g)  throws RuntimeException{
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, getWidth(), getHeight());
    initImg();

    BufferedImage img = null;

     g.drawImage(img, 0, 0, this);


    super.paintComponent(g);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM