[英]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());
}
}
任何帮助,将不胜感激。
paintComponent(this.getGraphics());
- 不 。 您永远不必显式调用paintComponent
。 而是调用repaint()
。
super.paintComponent(g);
应该在paintComponent
方法的开始处或至少在使用Graphics
上下文进行任何绘画之前调用。
不要在paintComponent
方法中加载图像。 一种选择是将缓存保留在Map<String, Image>
。 这样,您可以轻松地引用它们,而不必在每次更改时都加载它们。 总的来说这是不是一个巨大的问题,你是否决定缓存与否。 您可以只在repaintBackground
方法中加载它。
保持班级成员的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); } }
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.