• 关于

    java awt示例

    的搜索结果

回答

java swing中在jTable中添加多个复选框的方式如下: import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.table.*; public class MyFirstJFrame extends JFrame { // 作为测试的main方法 public static void main(String[] args) { new MyFirstJFrame().setVisible(true); } /** * 构造方法 */ public MyFirstJFrame() { InitialComponent(); } /** * 初始化组件的方法 */ private void InitialComponent(){ // 设置窗体参数 // 设置布局模式 setLayout(null); // 设置窗体大小 setSize(480, 360); // 设置窗体居中(非常规方法) setLocationRelativeTo(null); // 关闭窗体退出程序 setDefaultCloseOperation(DISPOSE_ON_CLOSE); // 初始化面板 panel = new JPanel(); panel.setSize(this.getWidth(), this.getHeight()); panel.setLocation(0,0); panel.setLayout(null); // 初始化表格 table = new JTable(new DefaultTableModel(new Object[][]{{"第一行"},{"第二行"},{"第三行"},{"第四行"}}, new String[]{"测试行1","测试行2"}){ /* (non-Javadoc) * 重写方法,判断表单元格是否可编辑 * 可以通过row和column索引判断某一个单元格是否可编辑 * 此处设为都不可编辑 * @see javax.swing.table.DefaultTableModel#isCellEditable(int, int) */ @Override public boolean isCellEditable(int row, int column) { return false; } }); // 开始向表格中添加复选框(注意:此示例较为简单,缺省很多判断,也没有动态代码支持) // 通过设置列渲染 // 方法一:直接方式 使用TableColumn的setCellRenderer方法(推荐) // 此方法可以设置某一列的渲染(即使用某一个组件--即控件来显示单元格数据) table.getColumnModel().getColumn(1).setCellRenderer(new TableCellRenderer(){ /*(non-Javadoc) * 此方法用于向方法调用者返回某一单元格的渲染器(即显示数据的组建--或控件) * 可以为JCheckBox JComboBox JTextArea 等 * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) */ @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // 创建用于返回的渲染组件 JCheckBox ck = new JCheckBox(); // 使具有焦点的行对应的复选框选中 ck.setSelected(isSelected); // 设置单选box.setSelected(hasFocus); // 使复选框在单元格内居中显示 ck.setHorizontalAlignment((int) 0.5f); return ck; }}); // 方法二:先设置列编辑器,然后设置单元格渲染 // 设置列编辑器 // 在以复选框为对象设置列编辑器时,必须保证该列能够被编辑,否则无法更改状态 // (此步骤可以省略,省略时不要忘记将列设为不可编辑) // table.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(new JCheckBox())); // 设置单元格渲染(这里是设置表格级别的渲染) /*table.setDefaultRenderer(Object.class, new TableCellRenderer(){ @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // 判断是否为需要渲染的列 if(column == 1){ // 和方法一基本一致 JCheckBox box = new JCheckBox(); box.setSelected(isSelected); // 设置单选box.setSelected(hasFocus); box.setHorizontalAlignment((int) CENTER_ALIGNMENT); // 0.5f return box; } // 如果不是需要渲染的列,封装文本域显示数据 return new JTextArea(value.toString()); }});*/ // 在多选是需要按住Ctrl键或者鼠标按住拖过连续的需要选中的行,应该给用户说明 // 第一种方法是被推荐的,因为它具有选中的高亮显示,界面能更加友好 table.setSize(panel.getWidth(),panel.getHeight() - 90); table.setLocation(0, 0); btn = new JButton("Test"); btn.setSize(80,40); btn.setLocation((panel.getWidth()) / 2 - 40, panel.getHeight() - 80); // 按钮点击时显示当前选中项 btn.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { for(int rowindex : table.getSelectedRows()){ JOptionPane.showMessageDialog(null, rowindex + " " + table.getValueAt(rowindex, 0)); } }}); panel.add(table); panel.add(btn); this.add(panel); } // 定义一些必要的组件 private JPanel panel; private JTable table; private JButton btn; }

蛮大人123 2019-12-02 01:56:29 0 浏览量 回答数 0

回答

您的代码从后台线程更新UI,这绝对是不允许的。您需要确保从FX Application Thread更新。您还想尝试“限制”实际的UI更新,以使每个JavaFX框架渲染不超过一次。最简单的方法是使用AnimationTimer,handle()每次渲染框架时都会调用。 这是执行此操作的代码版本: import java.awt.Dimension; import java.awt.Image; import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; import java.awt.image.BufferedImage; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicReference; import org.tc33.jheatchart.HeatChart; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.embed.swing.SwingFXUtils; import javafx.scene.Scene; import javafx.scene.image.ImageView; import javafx.scene.layout.VBox; import javafx.stage.Stage; public class Main extends Application { ImageView imageView = new ImageView(); final int scale = 15; @Override public void start(Stage primaryStage) { AtomicReference<BufferedImage> image = new AtomicReference<>(); Thread generator = new Thread(() -> { int col = 0; LinkedList<Long> fps = new LinkedList<>(); while (true) { fps.add(System.currentTimeMillis()); double[][] matrix = new double[48][128]; for (int i = 0; i < 48; i++) { for (int j = 0; j < 128; j++) { matrix[i][j] = col == j ? Math.random() : 0; } } col = (col + 1) % 128; HeatChart heatChart = new HeatChart(matrix, 0, 1); heatChart.setShowXAxisValues(false); heatChart.setShowYAxisValues(false); heatChart.setLowValueColour(java.awt.Color.black); heatChart.setHighValueColour(java.awt.Color.white); heatChart.setAxisThickness(0); heatChart.setChartMargin(0); heatChart.setCellSize(new Dimension(1, 1)); long currentTime = System.currentTimeMillis(); fps.removeIf(elem -> currentTime - elem > 1000); System.out.println(fps.size()); image.set((BufferedImage) scale(heatChart.getChartImage(), scale)); } }); VBox box = new VBox(); box.getChildren().add(imageView); Scene scene = new Scene(box, 1920, 720); primaryStage.setScene(scene); primaryStage.show(); generator.setDaemon(true); generator.start(); AnimationTimer animation = new AnimationTimer() { @Override public void handle(long now) { BufferedImage img = image.getAndSet(null); if (img != null) { imageView.setImage(SwingFXUtils.toFXImage(img, null)); } } }; animation.start(); } public static void main(String[] args) { launch(args); } private static Image scale(Image image, int scale) { BufferedImage res = new BufferedImage(image.getWidth(null) * scale, image.getHeight(null) * scale, BufferedImage.TYPE_INT_ARGB); AffineTransform at = new AffineTransform(); at.scale(scale, scale); AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); return scaleOp.filter((BufferedImage) image, res); } } 使用AtomicReference来包装缓冲的图像可确保在两个线程之间安全地共享它。 在我的机器上,每秒可生成约130张图像;请注意,并非全部显示,因为每次JavaFX图形框架显示一帧(通常以60fps的速度调节)时,仅显示最新的一帧。 如果要确保显示所有生成的图像,即以JavaFX帧速率限制图像的生成,则可以使用a BlockingQueue存储图像: // AtomicReference<BufferedImage> image = new AtomicReference<>(); // Size of the queue is a trade-off between memory consumption // and smoothness (essentially works as a buffer size) BlockingQueue<BufferedImage> image = new ArrayBlockingQueue<>(5); // ... // image.set((BufferedImage) scale(heatChart.getChartImage(), scale)); try { image.put((BufferedImage) scale(heatChart.getChartImage(), scale)); } catch (InterruptedException exc) { Thread.currentThread.interrupt(); } 和 @Override public void handle(long now) { BufferedImage img = image.poll(); if (img != null) { imageView.setImage(SwingFXUtils.toFXImage(img, null)); } } 代码非常低效,因为您HeatChart每次迭代都会生成一个新矩阵new ,等等。这导致在堆上创建许多对象并迅速将其丢弃,这可能导致GC过于频繁地运行,尤其是在小型内存计算机上。就是说,我在最大堆大小设置为64MB(-Xmx64m)的情况下运行了该程序,它仍然运行良好。您也许可以优化代码,但是使用AnimationTimer如上所述的,更快地生成图像不会对JavaFX框架造成任何额外的压力。我建议调查使用HeatChart(即setZValues())的可变性,以避免创建过多的对象,和/或PixelBuffer直接将数据写入图像视图(这需要在FX Application Thread上完成)。 这是一个不同的示例,它使用一个屏幕外int[]数组来计算数据,并使用一个屏幕上int[]数组来显示(几乎)完全最小化对象的创建。有一些低级线程详细信息,以确保仅以一致的状态看到屏幕上的阵列。屏幕上的数组用于下方的,而数组PixelBuffer又用于WritableImage。 此类生成图像数据: import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; public class ImageGenerator { private final int width; private final int height; // Keep two copies of the data: one which is not exposed // that we modify on the fly during computation; // another which we expose publicly. // The publicly exposed one can be viewed only in a complete // state if operations on it are synchronized on this object. private final int[] privateData ; private final int[] publicData ; private final long[] frameTimes ; private int currentFrameIndex ; private final AtomicLong averageGenerationTime ; private final ReentrantLock lock ; private static final double TWO_PI = 2 * Math.PI; private static final double PI_BY_TWELVE = Math.PI / 12; // 15 degrees public ImageGenerator(int width, int height) { super(); this.width = width; this.height = height; privateData = new int[width * height]; publicData = new int[width * height]; lock = new ReentrantLock(); this.frameTimes = new long[100]; this.averageGenerationTime = new AtomicLong(); } public void generateImage(double angle) { // compute in private data copy: int minDim = Math.min(width, height); int minR2 = minDim * minDim / 4; for (int x = 0; x < width; x++) { int xOff = x - width / 2; int xOff2 = xOff * xOff; for (int y = 0; y < height; y++) { int index = x + y * width; int yOff = y - height / 2; int yOff2 = yOff * yOff; int r2 = xOff2 + yOff2; if (r2 > minR2) { privateData[index] = 0xffffffff; // white } else { double theta = Math.atan2(yOff, xOff); double delta = Math.abs(theta - angle); if (delta > TWO_PI - PI_BY_TWELVE) { delta = TWO_PI - delta; } if (delta < PI_BY_TWELVE) { int green = (int) (255 * (1 - delta / PI_BY_TWELVE)); privateData[index] = (0xff << 24) | (green << 8); // green, fading away from center } else { privateData[index] = 0xff << 24; // black } } } } // copy computed data to public data copy: lock.lock(); try { System.arraycopy(privateData, 0, publicData, 0, privateData.length); } finally { lock.unlock(); } frameTimes[currentFrameIndex] = System.nanoTime() ; int nextIndex = (currentFrameIndex + 1) % frameTimes.length ; if (frameTimes[nextIndex] > 0) { averageGenerationTime.set((frameTimes[currentFrameIndex] - frameTimes[nextIndex]) / frameTimes.length); } currentFrameIndex = nextIndex ; } public void consumeData(Consumer<int[]> consumer) { lock.lock(); try { consumer.accept(publicData); } finally { lock.unlock(); } } public long getAverageGenerationTime() { return averageGenerationTime.get() ; } } 这是UI: import java.nio.IntBuffer; import javafx.animation.AnimationTimer; import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.Label; import javafx.scene.image.ImageView; import javafx.scene.image.PixelFormat; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class AnimationApp extends Application { private final int size = 400 ; private IntBuffer buffer ; @Override public void start(Stage primaryStage) throws Exception { // background image data generation: ImageGenerator generator = new ImageGenerator(size, size); // Generate new image data as fast as possible: Thread thread = new Thread(() -> { while( true ) { long now = System.currentTimeMillis() ; double angle = 2 * Math.PI * (now % 10000) / 10000 - Math.PI; generator.generateImage(angle); } }); thread.setDaemon(true); thread.start(); generator.consumeData(data -> buffer = IntBuffer.wrap(data)); PixelFormat<IntBuffer> format = PixelFormat.getIntArgbPreInstance() ; PixelBuffer<IntBuffer> pixelBuffer = new PixelBuffer<>(size, size, buffer, format); WritableImage image = new WritableImage(pixelBuffer); BorderPane root = new BorderPane(new ImageView(image)); Label fps = new Label("FPS: "); root.setTop(fps); Scene scene = new Scene(root); primaryStage.setScene(scene); primaryStage.setTitle("Give me a ping, Vasili. "); primaryStage.show(); AnimationTimer animation = new AnimationTimer() { @Override public void handle(long now) { // Update image, ensuring we only see the underlying // data in a consistent state: generator.consumeData(data -> { pixelBuffer.updateBuffer(pb -> null); }); long aveGenTime = generator.getAverageGenerationTime() ; if (aveGenTime > 0) { double aveFPS = 1.0 / (aveGenTime / 1_000_000_000.0); fps.setText(String.format("FPS: %.2f", aveFPS)); } } }; animation.start(); } public static void main(String[] args) { Application.launch(args); } } 对于不依赖JavaFX 13的版本PixelBuffer,您可以修改该类以使用PixelWriter(AIUI,效率不高,但在此示例中运行得一样顺畅): // generator.consumeData(data -> buffer = IntBuffer.wrap(data)); PixelFormat<IntBuffer> format = PixelFormat.getIntArgbPreInstance() ; // PixelBuffer<IntBuffer> pixelBuffer = new PixelBuffer<>(size, size, buffer, format); // WritableImage image = new WritableImage(pixelBuffer); WritableImage image = new WritableImage(size, size); PixelWriter pixelWriter = image.getPixelWriter() ; 和 AnimationTimer animation = new AnimationTimer() { @Override public void handle(long now) { // Update image, ensuring we only see the underlying // data in a consistent state: generator.consumeData(data -> { // pixelBuffer.updateBuffer(pb -> null); pixelWriter.setPixels(0, 0, size, size, format, data, 0, size); }); long aveGenTime = generator.getAverageGenerationTime() ; if (aveGenTime > 0) { double aveFPS = 1.0 / (aveGenTime / 1_000_000_000.0); fps.setText(String.format("FPS: %.2f", aveFPS)); } } }; 回答来源:Stack Overflow

montos 2020-03-27 13:24:04 0 浏览量 回答数 0

问题

用JavaScript编写一个Java虚拟机?谈谈哗众取宠的BicaVM 400 请求报错 

kun坤 2020-05-29 09:57:19 2 浏览量 回答数 1

阿里云高校特惠,助力学生创业梦!0元体验,快速入门云计算!

学生动手场景应用,快速了解并掌握云服务器的各种新奇玩法!

回答

1. Java事件处理三要素: 1) 事件源(Event Source):即事件发生的场所,就是指各个组件,如按钮等,点击按钮其实就是组件上发生的一个事件; 2) 事件(Event):事件封装了组件上发生的事情,比如按钮单击、按钮松开等等; 3) 事件监听器(Event Listener):负责监听事件源上发生的特定类型的事件,当事件到来时还必须负责处理相应的事件; 2. 事件处理的机制: 1) 首先事件是有不同的类别的,比如按钮单击、菜单项单击等事件就属于“动作事件”(Action Event),而关闭窗口、最小化窗口等事件就属于“窗口事件”(Window Event); 2) 不同类型的事件需要用不同类型的监听器监听; 3) 而监听器是一种类对象,这种类必须实现监听器接口(Listener),对于监听不同类型的事件AWT库准备了不同类型的监听器接口,比如要监听动作事件就必须实现ActionListener接口,监听窗口事件就必须实现WindowListener接口; !监听器中最重要的就是事件处理方法了,监听器必须在接受事件之后进行处理(响应); 4) 如何实现监听? i. 首先事件源(发生事件的组件)必须同意我身上发生的事件允许那些监听器监听; ii. 也就是说想监听它身上发生的事件的监听器必须到它这里注册,即组件必须调用方法addXxxListener将监听器注册到它的监听器列表中; iii. 当事件发生时就会将事件对象(Event)发送到所有注册过的监听器那里进行处理; 5) 事件源、事件、监听器的对应关系: i. 首先一个事件源可以产生多种类型的事件,比如窗口右上角的×按钮,当单击它时就会产生两种类型的事件,一个是按钮单击事件(属于Action Event),另一个是窗口关闭事件(属于Window Event); ii. 监听器接口是什么类型就发送什么类型的事件:如果注册的监听器实现的是ActionEvent的接口,那么上述×按钮就只发送按钮单击事件给它而不会发送窗口关闭事件,除非监听器同时实现了两种类型的接口,那么该监听器就会同时受到两种类型的事件; iii. 一个事件源可以注册多个监听器:一般符合逻辑的编程思想就是不同监听器监听、处理不同类型的事件,因此对于可以产生多种类型事件的事件源会注册多种类型的监听器,分别负责处理产生的多种事件; !!当然一个事件源也可以注册多个相同类型的监听器,即比对于同一个事件(按钮单击),事件源注册多个实现ActionListener接口的监听器,那么这些监听器都会受到该事件,可能会疑问,这不是多此一举吗?一种事件就给出一种处理不是很好吗?那是因为有些情况下可能需要一个事件触发多种动作,每个监听器负责实现一个动作; iv. 一个监听器可以监听多个事件源上的事件,即多个不同的组件用addXxxListener方法注册同一个监听器,那么当不同事件到来时监听器会调用其不同方法进行处理,或者在一个方法内部判断传进来的是什么事件,再进行特殊的处理; 3. 编写事件处理程序的基本流程: 1) 首先需要实现监听器类:自己编写一个类,至少要实现一种类型的监听器接口,并实现接口中所有的事件处理方法; 2) 创建组件,并对组件注册响应的监听器:首先需要创建监听器对象,将监听器对象作为参数传入组件的addXxxListener方法完成注册; 3) 全部工作完成,事件的处理完全自动进行; 4) 简单的示例:处理一个按钮的单击事件 [java] view plain copy public class AwtTest { Frame f = new Frame("Event Test"); TextField tf = new TextField(30); Button ok = new Button("OK"); class OkListener implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub System.out.println("OK button pushed!"); tf.setText("Hello!"); } } public void init() { f.add(tf); f.add(ok, BorderLayout.SOUTH); ok.addActionListener(new OkListener()); f.pack(); f.setVisible(true); } public static void main(String[] args) { new AwtTest().init(); } } !!完全按照讲述的顺序进行; !直接设置编辑框内文本的方法:void TextField.setText(String text); 4. 事件源-监听器多对多示例: [java] view plain copy public class AwtTest { Frame f = new Frame("Multiple Event Test"); TextArea ta = new TextArea(6, 40); Panel p = new Panel(); Button btn1 = new Button("button1"); Button btn2 = new Button("button2"); class Listener1 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub ta.append("Listener1 be activated! Event Source:" + e.getActionCommand() + "\n"); } } class Listener2 implements ActionListener { @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub ta.append("Listener2 be activated! Event Source:" + e.getActionCommand() + "\n"); } } public void init() { f.add(ta); p.add(btn1); p.add(btn2); f.add(p, BorderLayout.SOUTH); Listener1 l1 = new Listener1(); Listener2 l2 = new Listener2(); btn1.addActionListener(l1); btn2.addActionListener(l1); btn2.addActionListener(l2); f.pack(); f.setVisible(true); } public static void main(String[] args) { new AwtTest().init(); } } !可以看到按钮2可以同时触发两个监听器,输出两条消息,而监听器1同时监听并处理了两个按钮的消息;

1668934001470375 2019-12-02 01:02:20 0 浏览量 回答数 0

问题

未来有望干掉 Java 和 Python 的编程语言

游客pklijor6gytpx 2020-01-09 14:12:19 7 浏览量 回答数 2

问题

预测 | 未来有望干掉 Python 和 JavaScript 的编程语言?

茶什i 2020-01-15 18:29:13 181 浏览量 回答数 2

回答

示例代码: public class MyShowImage extends JFrame { // 保存当前操作的像素矩阵 private int currentPixArray[] = null; // 图像的路径 private String fileString = null; // 用于显示图像的标签 private JLabel imageLabel = null; // 加载的图像 private BufferedImage newImage; // 图像的高和宽 private int h, w; // 保存历史操作图像矩阵 private LinkedList<int[]> imageStack = new LinkedList<int[]>(); private LinkedList<int[]> tempImageStack = new LinkedList<int[]>(); public MyShowImage(String title) { super(title); this.setSize(800, 600); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 创建菜单 JMenuBar jb = new JMenuBar(); JMenu fileMenu = new JMenu("文件"); jb.add(fileMenu); JMenuItem openImageMenuItem = new JMenuItem("打开图像"); fileMenu.add(openImageMenuItem); openImageMenuItem.addActionListener(new OpenListener()); JMenuItem exitMenu = new JMenuItem("退出"); fileMenu.add(exitMenu); exitMenu.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.exit(0); } }); JMenu operateMenu = new JMenu("图像处理"); jb.add(operateMenu); JMenuItem RGBtoGrayMenuItem = new JMenuItem("灰度图像转换"); operateMenu.add(RGBtoGrayMenuItem); RGBtoGrayMenuItem.addActionListener(new RGBtoGrayActionListener()); JMenuItem balanceMenuItem = new JMenuItem("均衡化"); operateMenu.add(balanceMenuItem); balanceMenuItem.addActionListener(new BalanceActionListener()); JMenu frontAndBackMenu = new JMenu("历史操作"); jb.add(frontAndBackMenu); JMenuItem backMenuItem = new JMenuItem("后退"); frontAndBackMenu.add(backMenuItem); backMenuItem.addActionListener(new BackActionListener()); JMenuItem frontMenuItem = new JMenuItem("前进"); frontAndBackMenu.add(frontMenuItem); frontMenuItem.addActionListener(new FrontActionListener()); this.setJMenuBar(jb); imageLabel = new JLabel(""); JScrollPane pane = new JScrollPane(imageLabel); this.add(pane, BorderLayout.CENTER); this.setVisible(true); } private class OpenListener implements ActionListener { public void actionPerformed(ActionEvent e) { JFileChooser jc = new JFileChooser(); jc.setFileFilter(new FileFilter() { public boolean accept(File f) { // 设定可用的文件的后缀名 if (f.getName().endsWith(".jpg") || f.isDirectory()|| f.getName().endsWith(".gif") || f.getName().endsWith(".bmp")) { return true; } return false; } public String getDescription() { return "图片(*.jpg,*.gif,*bmp)"; } }); int returnValue = jc.showOpenDialog(null); if (returnValue == JFileChooser.APPROVE_OPTION) { File selectedFile = jc.getSelectedFile(); if (selectedFile != null) { fileString = selectedFile.getAbsolutePath(); try { newImage = ImageIO.read(new File(fileString)); w = newImage.getWidth(); h = newImage.getHeight(); currentPixArray = getPixArray(newImage, w, h); imageStack.clear(); tempImageStack.clear(); imageStack.addLast(currentPixArray); imageLabel.setIcon(new ImageIcon(newImage)); } catch (IOException ex) { System.out.println(ex); } } } MyShowImage.this.repaint(); // MyShowImage.this.pack(); } } // ////////////////菜单监听器/////////// private class RGBtoGrayActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { int[] resultArray = RGBtoGray(currentPixArray); imageStack.addLast(resultArray); currentPixArray = resultArray; showImage(resultArray); tempImageStack.clear(); } } private class BalanceActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { int[] resultArray = balance(currentPixArray); imageStack.addLast(resultArray); currentPixArray = resultArray; showImage(resultArray); tempImageStack.clear(); } } private class BackActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (imageStack.size() <= 1) { JOptionPane.showMessageDialog(null, "此幅图片的处理已经没有后退历史操作了", "提示", JOptionPane.INFORMATION_MESSAGE); } else { tempImageStack.addLast(imageStack.removeLast()); currentPixArray = imageStack.getLast(); showImage(currentPixArray); } } } private class FrontActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (tempImageStack.size() < 1) { JOptionPane.showMessageDialog(null, "此幅图片的处理已经没有前进历史操作了", "提示", JOptionPane.INFORMATION_MESSAGE); } else { currentPixArray = tempImageStack.removeFirst(); imageStack.addLast(currentPixArray); showImage(currentPixArray); } } } // ////////////////获取图像像素矩阵///////// private int[] getPixArray(Image im, int w, int h) { int[] pix = new int[w * h]; PixelGrabber pg = null; try { pg = new PixelGrabber(im, 0, 0, w, h, pix, 0, w); if (pg.grabPixels() != true) try { throw new java.awt.AWTException("pg error" + pg.status()); } catch (Exception eq) { eq.printStackTrace(); } } catch (Exception ex) { ex.printStackTrace(); } return pix; } // ////////////////显示图片/////////// private void showImage(int[] srcPixArray) { Image pic = createImage(new MemoryImageSource(w, h, srcPixArray, 0, w)); ImageIcon ic = new ImageIcon(pic); imageLabel.setIcon(ic); imageLabel.repaint(); } // ////////////////灰度转换/////////// private int[] RGBtoGray(int[] ImageSource) { int[] grayArray = new int[h * w]; ColorModel colorModel = ColorModel.getRGBdefault(); int i, j, k, r, g, b; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { k = i * w + j; r = colorModel.getRed(ImageSource[k]); g = colorModel.getGreen(ImageSource[k]); b = colorModel.getBlue(ImageSource[k]); int gray = (int) (r * 0.3 + g * 0.59 + b * 0.11); r = g = b = gray; grayArray[i * w + j] = (255 << 24) | (r << 16) | (g << 8) | b; } } return grayArray; } // ///////////////图像均衡化/////////// private int[] balance(int[] srcPixArray) { int[] histogram = new int[256]; int[] dinPixArray = new int[w * h]; for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int grey = srcPixArray[i * w + j] & 0xff; histogram[grey]++; } } double a = (double) 255 / (w * h); double[] c = new double[256]; c[0] = (a * histogram[0]); for (int i = 1; i < 256; i++) { c[i] = c[i - 1] + (int) (a * histogram[i]); } for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int grey = srcPixArray[i * w + j] & 0x0000ff; int hist = (int) c[grey]; dinPixArray[i * w + j] = 255 << 24 | hist << 16 | hist << 8 | hist; } } return dinPixArray; } public static void main(String[] args) { new MyShowImage("ShowImage"); } }

蛮大人123 2019-12-02 02:12:36 0 浏览量 回答数 0
阿里云大学 云服务器ECS com域名 网站域名whois查询 开发者平台 小程序定制 小程序开发 国内短信套餐包 开发者技术与产品 云数据库 图像识别 开发者问答 阿里云建站 阿里云备案 云市场 万网 阿里云帮助文档 免费套餐 开发者工具 企业信息查询 小程序开发制作 视频内容分析 企业网站制作 视频集锦 代理记账服务 2020阿里巴巴研发效能峰会 企业建站模板 云效成长地图 高端建站