java - El programa no tiene acceso al método paintComponent() de la clase extendida JPanel
swing jframe (1)
No está claro por qué está pasando byte[]
, pero parece que desea actualizar el Icon
un componente con una miniatura gris. El siguiente ejemplo crea iconos en escala de grises de iconos de muestra existentes y usa setIcon()
para hacer la actualización. Un enfoque similar funciona con cualquier Image
. Consulte también este ejemplo que sugiere ColorConvertOp
, y este ejemplo que actualiza componentes completos en lugar de iconos.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.Timer;
import javax.swing.UIManager;
/**
* @see https://stackoverflow.com/a/12228640/230513
* @see https://stackoverflow.com/a/7935040/230513
*/
public class GrayIcons extends JPanel {
private List<Icon> list = new ArrayList<Icon>();
private List<JToggleButton> buttons = new ArrayList<JToggleButton>();
private Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
update();
}
});
public GrayIcons() {
this.setLayout(new GridLayout(1, 0));
list.add(getGray(UIManager.getIcon("OptionPane.errorIcon")));
list.add(getGray(UIManager.getIcon("OptionPane.informationIcon")));
list.add(getGray(UIManager.getIcon("OptionPane.warningIcon")));
list.add(getGray(UIManager.getIcon("OptionPane.questionIcon")));
for (Icon icon : list) {
JToggleButton jtb = new JToggleButton(icon);
buttons.add(jtb);
this.add(jtb);
}
timer.start();
}
private void update() {
Collections.shuffle(list);
int index = 0;
for (JToggleButton b : buttons) {
b.setIcon(list.get(index++));
}
}
/**
* @see https://stackoverflow.com/q/5830533/230513
* @see https://stackoverflow.com/a/3106550/230513
*/
private Icon getGray(Icon icon) {
final int w = icon.getIconWidth();
final int h = icon.getIconHeight();
GraphicsEnvironment ge =
GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gd.getDefaultConfiguration();
BufferedImage image = gc.createCompatibleImage(w, h);
Graphics2D g2d = image.createGraphics();
g2d.setPaint(new Color(0x00f0f0f0));
g2d.fillRect(0, 0, w, h);
icon.paintIcon(null, g2d, 0, 0);
BufferedImage gray = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_GRAY);
ColorConvertOp op = new ColorConvertOp(
image.getColorModel().getColorSpace(),
gray.getColorModel().getColorSpace(), null);
op.filter(image, gray);
return new ImageIcon(gray);
}
private void display() {
JFrame f = new JFrame("GrayIcons");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new GrayIcons().display();
}
});
}
}
Este es el JFrame
package client.connection;
import java.awt.Dimension;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import javax.swing.JFrame;
class DrawFrameRemoteControl extends JFrame
{
private DrawPanelRemoteControl imagePanel;
private ClientRemoteControlConnection clientRemoteControlConnection;
private ObjectInputStream clientInputStream;
private ObjectOutputStream clientOutputStream;
private Dimension imageDimension;
private Dimension serverDimension;
public DrawFrameRemoteControl(Dimension imageDimension,ClientRemoteControlConnection clientRemoteControlConnection,ObjectInputStream clientInputStream,ObjectOutputStream clientOutputStream,Dimension serverDimension)
{
super("Remote Desktop Control");
this.clientRemoteControlConnection=clientRemoteControlConnection;
this.clientInputStream=clientInputStream;
this.clientOutputStream=clientOutputStream;
this.imageDimension=imageDimension;
this.serverDimension=serverDimension;
imagePanel=new DrawPanelRemoteControl(imageDimension);
add(imagePanel);
setSize(imageDimension.width,imageDimension.height);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
}
void drawNewImageGrayscale(byte[] array)
{
imagePanel.setNewImageGrayscale(array);
imagePanel.repaint();
}
}
Y esta es la clase extendida de JPanel-
package client.connection;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Transparency;
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.MemoryImageSource;
import java.awt.image.Raster;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
class DrawPanelRemoteControl extends JPanel
{
private byte[] byteArray=null;
private Image image;
private JLabel imageLabel=new JLabel();
private Dimension imageDimension;
public DrawPanelRemoteControl(Dimension imageDimension)
{
this.imageDimension=imageDimension;
add(imageLabel);
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
System.out.println(".");
if(byteArray!=null)
{
image=getGrayscaleImageFromArray(byteArray,imageDimension.width,imageDimension.height);
imageLabel.setIcon(new ImageIcon(image));
}
}
private Image getGrayscaleImageFromArray(byte[] buffer, int width, int height)
{
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
int[] nBits = { 8 };
ColorModel cm = new ComponentColorModel(cs, nBits, false, true,Transparency.OPAQUE, DataBuffer.TYPE_BYTE);
SampleModel sm = cm.createCompatibleSampleModel(width, height);
DataBufferByte db = new DataBufferByte(buffer, width * height);
WritableRaster raster = Raster.createWritableRaster(sm, db, null);
BufferedImage result = new BufferedImage(cm, raster, false, null);
return result;
}
void setNewImageGrayscale(byte[] array)
{
this.byteArray=array;
this.intArray=null;
}
}
He intentado depurar el código, aunque imagePanel.repaint()
se está ejecutando muchas veces, el programa nunca llega al método paintComponent()
de la clase DrawPanelRemoteControl
.
¿Alguien puede darme alguna idea de por qué esto podría estar pasando? ¿Tiene algo que ver con el objeto imageDimension
?
Información adicional: En el método main()
, se DrawFrameRemoteControl
un objeto DrawFrameRemoteControl
y su drawNewImageGrayscale(byte[] arr)
se actualiza desde main()
cada segundo.