程序不访问扩展JPanel类的paintComponent()方法
这是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(); } }
这是扩展的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; } }
我已经尝试debugging代码,即使imagePanel.repaint()
被执行多次,程序也不会到达DrawPanelRemoteControl
类的paintComponent()
方法。
有人可以告诉我为什么这可能会发生? 它有什么关系imageDimension
对象?
附加信息:在main()
方法中,创build一个DrawFrameRemoteControl
对象,并且drawNewImageGrayscale(byte[] arr)
从main()
更新drawNewImageGrayscale(byte[] arr)
方法。
目前还不清楚为什么你要传递byte[]
,但看起来你想用灰色缩略图更新组件的Icon
。 下面的示例从现有的示例图标创build灰度图标,并使用setIcon()
进行更新。 类似的方法适用于任何Image
。 另请参阅build议使用ColorConvertOp
示例 ,此示例更新整个组件而不是图标。
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(); } }); } }