Я пытаюсь загрузить фоновое изображение с помощью JFileChooser, но когда операция завершается, метод paintcomponent() не вызывается как ожидалось. [EDIT] по этой причине, вместо красного шарика над фоновым изображением, у меня есть только красный шар.paintComponent не вызывается при вызове JScrollPane
Я прочитал в нескольких другом тем, что экземпляр моей Маппы объекта должен быть добавлен к раме: Why is paint()/paintComponent() never called? paintComponent not being called at the right time PaintComponent is not being called
Но это не решает мою проблему: Я создал JScrollPane, который получает свой компонент в конструктор и связывает JScrollPane и добавили его в основной раме с
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
Это код главного Gui
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
public class Gui implements ActionListener {
private JFrame frmEditor;
Mappa content;
private JMenuItem mntmSfondo;
private JScrollPane scrollabile;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Gui window = new Gui();
window.frmEditor.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Gui() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frmEditor = new JFrame();
frmEditor.setFont(UIManager.getFont("TextArea.font"));
frmEditor.setBounds(50, 50, 1024, 768);
frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmEditor.getContentPane().setLayout(new BorderLayout(0, 0));
JPanel panelTile = new JPanel();
panelTile.setLayout(new BorderLayout(0, 0));
JPanel panelStrum = new JPanel();
panelStrum.setLayout(new GridLayout(15, 2));
content = new Mappa(null);
content.setMinimumSize(new Dimension(150, 150));
scrollabile = new JScrollPane(content);
scrollabile
.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
scrollabile
.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);
inizializzaMenu();
}
/**
* Initialize the menu.
*/
private void inizializzaMenu() {
JMenuBar menuBar = new JMenuBar();
frmEditor.setJMenuBar(menuBar);
JMenu mnFile = new JMenu("File");
mnFile.setFont(UIManager.getFont("TextArea.font"));
JMenu mnAltro = new JMenu("Modify");
mnAltro.setFont(UIManager.getFont("TextArea.font"));
menuBar.add(mnAltro);
mntmSfondo = new JMenuItem("Load Background");
mntmSfondo
.setIcon(new ImageIcon(
Gui.class
.getResource("/com/sun/java/swing/plaf/windows/icons/TreeOpen.gif")));
mntmSfondo.setFont(UIManager.getFont("TextArea.font"));
mntmSfondo.addActionListener(this);
mnAltro.add(mntmSfondo);
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == mntmSfondo) {
JFileChooser fc = new JFileChooser("tuttiSfondi");
int result = fc.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File file = fc.getSelectedFile();
try {
content = new Mappa(file);
} catch (Exception ex) {
}
}
if (result == JFileChooser.CANCEL_OPTION) {
}
}
}
}
в то время как это код класса Маппа, что я хотел бы использовать для загрузки фона от JFileChooser.
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
public class Mappa extends JPanel {
Image immagine;
public Mappa(File fileImmagine) {
if (fileImmagine != null) {
BufferedImage img = null;
try {
img = ImageIO.read(new File(fileImmagine.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
this.immagine = img;
}
repaint();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.clearRect(0, 0, 4000, 4000);
g.drawImage(immagine, 0, 0, null);
g.setColor(Color.red);
g.fillOval(170, 170, 150, 150);
System.out.println("Called Repaint() on Mappa");
}
}
Проблема не в неправильном пути изображения, так как он загружает, если я установить путь на классе Маппа «вручную», давая путь вместо того, чтобы использовать new File(fileImmagine.getPath())
в ImageIO.read
, но paintComponent называется только один раз, когда конструктор Mappa вызывается из класса Gui
Я попытался добавить' scrollable.setViewportView (content); 'после и перед' frmEditor. getContentPane(). add (scrollabile, BorderLayout.CENTER); 'без каких-либо успехов. Предложение Вандала о добавлении функции setImage в класс Mappa фактически решило проблему, спасибо! – Kaeel
@Kaeel, идея состояла в том, чтобы вызвать 'scrollabile.setViewportView (content);' in' actionPerformed() 'сразу после перераспределения' Mappa'. Но замена изображения в существующем 'Mappa' проще. – tenorsax
Я только что пробовал; он действительно работает, и я также узнал новое. Простите, что у меня до сих пор нет репутации enuogh, чтобы поддержать вас обоих, я вернусь к этому вопросу и сделаю это, когда я получу 15 репутации! – Kaeel