Dibujar una imagen en JScrollPane dentro de la escala
Frecuentes
Visto 3,547 equipos
2
Tengo un panel de desplazamiento donde cargar una imagen. No usaré esta imagen con su tamaño natural, y si esta imagen es demasiado grande, no activaré la barra de desplazamiento, pero esta instrucción
g.drawImage(imagen, 0, 0, obtenerAncho(), obtenerAltura(), esto);
imagen a escala para colocar en scrollpane. ¿Qué puedo hacer?
Interfaz gráfica de usuario de clase:
importar java.awt.*; importar java.awt.event.*; importar java.io.Archivo; importar javax.swing.*; public class Gui implementa ActionListener { private JFrame frmEditor; contenido privado de Mappa; JMenuItem privado mntmSfondo; JScrollPane privado desplazable; /** * Iniciar la aplicacion. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Gui window = new Gui(); window.frmEditor.setVisible(true); } catch ( Excepción e) { e.printStackTrace(); } } }); } /** * Crear la aplicación. */ public Gui() { inicializar(); } /** * Inicializar el contenido del marco. */ 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(nuevo BorderLayout(0, 0)); JPanel panelTile = new JPanel(); panelTile.setLayout(nuevo BorderLayout(0, 0)); contenido = nuevo Mappa (nulo); content.setMinimumSize(nueva Dimensión(150, 150)); scrollable = new JScrollPane(contenido); frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER); inicializaMenu(); } /** * Inicializar el menú. */ private void inizializzaMenu() { JMenuBar menuBar = new JMenuBar(); frmEditor.setJMenuBar(menuBar); JMenu mnAltro = new JMenu("Modificar"); menuBar.add(mnAltro); mntmSfondo = new JMenuItem("Cargar fondo"); mntmSfondo.addActionListener(esto); mnAltro.add(mntmFondo); } public void actionPerformed(ActionEvent e) { Fuente del objeto = e.getSource(); if (fuente == mntmSfondo) { JFileChooser fc = new JFileChooser("tuttiSfondi"); resultado int = fc.showOpenDialog(nulo); if (resultado == JFileChooser.APPROVE_OPTION) { Archivo archivo = fc.getSelectedFile(); intente { contenido.setImage(archivo); //contenido = nuevo Mappa(archivo); //scrollabile.setViewportView(contenido); } catch (Excepción ex) { } } if (resultado == JFileChooser.CANCEL_OPTION) { } } } }
Mapa de clase:
importar java.awt.*; importar java.awt.image.BufferedImage; importar java.io.*; importar javax.imageio.ImageIO; importar javax.swing.*; clase pública Mappa extiende JPanel { imagen BufferedImage; public Mappa(File fileImmagine) { if (fileImmagine != null ) { BufferedImage img = null; prueba { img = ImageIO.read(nuevo archivo(fileImmagine.getPath())); } catch (IOException e) { e.printStackTrace(); } esta.imagen = img; } repintar(); } public void setImage(File file) throws IOException { this.immagine = ImageIO.read(file); Nombre de cadena = archivo.getPath(); Sistema.out.println(nombre); repintar(); } public void paintComponent(Gráficos g) { super.paintComponent(g); g.clearRect(0, 0, 4000, 4000); g.drawImage(this.immagine, 0, 0, getWidth(), getHeight(), this); System.out.println("Repintado llamado() en Mappa"); } }
2 Respuestas
2
JScrollPane
, o más al grano JViewport
utilizará el tamaño preferido del componente (o en este caso, la "vista") como base para determinar qué tan grande debe ser la vista.
Cuando la vista se expande más allá del tamaño del panel de desplazamiento, mostrará las barras de desplazamiento.
Así que básicamente, necesitas anular el getPreferredSize
de la public class Mappa extends JPanel {
tablero, por ejemplo
public class Mappa extends JPanel {
//...
public Dimension getPreferredSize() {
return immagine == null ? new Dimension(200, 200) : new Dimension(immagine.getWidth(), immagine.getHeight());
}
//...
}
Esto animará a los JViewport
ser siempre del mismo tamaño que la imagen.
Además, dos cosas...
Primero, no debes confiar en números mágicos, por ejemplo
g.clearRect(0, 0, 4000, 4000);
Debería ser más como...
g.clearRect(0, 0, getWidth(), getHeight());
Y en segundo lugar,
super.paintComponent(g);
Haré esto de cualquier manera, así que llamando clearRect
es algo sin sentido...
También te puede interesar echar un vistazo a Scrollable
, pero es un tema bastante avanzado
respondido 27 nov., 13:22
2
No usaré esta imagen con su tamaño natural, y si esta imagen es demasiado grande, no activaré la barra de desplazamiento,
Usar JLabel
para contener la imagen y envolverla en un JScrollPane
debe lograr fácilmente lo que desea. Tome sugerencias del siguiente ejemplo:
class AFrame extends JFrame
{
public AFrame()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Image view Demo with JScrollPane");
ImageIcon image = new ImageIcon("myImage.png"); // pass the file location of an image
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new AFrame().setVisible(true);
}
});
}
}
respondido 27 nov., 13:22
Creo que no puedo usar este método porque después necesito dibujar sobre esta imagen. Lo uso como fondo. - aura
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas java swing jscrollpane bufferedimage paintcomponent or haz tu propia pregunta.
Me estoy perdiendo el punto de que, si necesito
JScrollPane
reaccionar a la vista de una imagen por qué incluso usando unJPanel
y anularpaintComponent
¡función!JLabel
ya está haciendo esto por mí. no es un pequeño gasto innecesario. :( - Sage@Sage Solo estoy basando la respuesta en lo que ha hecho el OP, espero que podamos enseñarles algo sobre cómo funcionan las cosas en el proceso. Y sí, a menos que esté realizando algún tipo de procesamiento y/o cambio de tamaño dinámico, un
JLabel
es generalmente un mejor enfoque. Pero después de muchos años, tiendo a no usarJLabel
tanto ... como quiero hacer un cambio de escala dinámico de la imagen: P - Programador locoTu punto de respuesta me quedó más claro desde el principio, fuera de curso. Solo quería decir, y dije :) - Sage
Al agregar el método anulado getPrefferedSize(), resuelvo el problema con la barra de desplazamiento. Gracias. Pero necesito cargar una imagen con su tamaño real, este problema aún no se resuelve. Ejemplo: tengo una imagen de 1920*1080 y mi JFrame se inicializa aquí: frmEditor.setBounds(50, 50, 1024, 768); Así que mi imagen está escalada... - aura
@MadProgrammer Sí, sé que la instrucción g.clearRect(...) es estúpida en este caso. Son los restos de una mala programación. Soy muy muy principiante. :-) Gracias por su paciencia. - aura