自动在 ImageIcon 旁边放置一个 jTextField

Automate placing a jTextField next to an ImageIcon

我想自动将 jTextField 放在同一行的 ImageIcon 旁边,行数不限。

我需要根据我作为输入提供的图像数量来执行此过程,这就是手动解决方案对我不起作用的原因。

这是我想要的示例。正如您所看到的,旁边有一个文本字段的图像可以满足我需要的行数:

我正在使用 Java Swing

这是我现在在这个例子中尝试的方法:

public class ImageTextModel {

        private final List<ImageText> images;

        public ImageTextModel() {
            this.images = new ArrayList<>();

            // This is where you would read the OCR images and OCR text from your
            // file system and add the information to the List. I generated OCR images to
            // make the GUI look more realistic.
            /*  
            String name = "John Smith";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "George Washington";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "John Adams";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "Thomas Jefferson";
            images.add(new ImageText(createBufferedImage(name), name));
             */
            String path = "C:\Users\ibrahim\Desktop\MARKS";
            File folder = new File(path);
            File[] listOfFiles = folder.listFiles();
            DefaultListModel listModel = new DefaultListModel();
            int count = 0;
            for (int i = 0; i < listOfFiles.length; i++) {
                System.out.println("check path" + listOfFiles[i]);
                String name = listOfFiles[i].toString();
                // load only png
                if (name.endsWith("png")) {
                    images.add(new ImageText(createBufferedImage(name), name));
                }

            }       }

这是 result 它显示的是图像路径而不是图像

简介

这是我想出的 GUI。

要使用此 GUI,您可以 select 使用鼠标在要更正的第一行中输入更正后的文本。

按 Enter 键将光标置于下一行。您可以在不输入任何内容的情况下按 Enter 键跳过一行。

完成所有更正后,左键单击“保存更正”按钮。

说明

当我创建 Swing GUI 时,我使用 model / view / controller (MVC) 模式。这种模式使我能够将我的关注点分开并一次专注于 GUI 的一部分。

使用JavaSwing,MVC模式是这样实现的:

  1. 视图从模型中读取信息。
  2. 视图不更新模型。
  3. 控制器更新模型并重新绘制/重新验证视图。

通常没有一个控制器 class 可以“一统天下”。每个 ActionListener 作为一个独立的控制器。

对于这个项目,我创建了两个模型 classes、一个视图 class、一个 JTable 单元格渲染器 class 和一个控制器 class .

型号

我创建了两个模型 classes。 ImageText class 包含 OCR 图像、OCR 文本和更正后的文本。这使更正保持独立,并允许更容易地验证代码的正确性。

ImageTextModel class 拥有 java.util.ListImageText 个实例。由于您没有提供任何 OCR 图像示例,我从文本中创建了一些。这是您读取 OCR 图像和 OCR 文本并将值放入 List.

的地方

查看

我通过调用 SwingUtilities invokeLater 方法启动了 Swing 应用程序。此方法确保所有 Swing 组件都在 Event Dispatch Thread.

上创建和执行

我创建了一个 JFrame 和两个 JPanelsJFrame 方法必须按特定顺序执行。这是我用于所有 Swing 应用程序的顺序。

上面JPanel持有JTable。较低的 JPanel 持有 JButtonImageCellRenderer class 允许我在 JTable.

中显示 BufferedImage

我使用 Swing layout managers 创建 JPanels 并打包 JFrame。这允许布局管理器放置 Swing 组件并使 JFrame 尽可能小。

控制器

ButtonListener class 打印更正后的文本。您可以在此处将更正后的 OCR 文本写入文件系统。

代码

这是完整的可运行代码。我将所有 classes 都放在 classes 中,这样我就可以 post 将代码作为一个块。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;

public class ImageTextGUI implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ImageTextGUI());
    }
    
    private final OCRTableModel tableModel;
    
    private final ImageTextModel model;
    
    public ImageTextGUI() {
        this.tableModel = new OCRTableModel();
        this.model = new ImageTextModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Image Text GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        frame.add(createJTablePanel(), BorderLayout.CENTER);
        frame.add(createButtonPanel(), BorderLayout.AFTER_LAST_LINE);
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JPanel createJTablePanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        tableModel.addColumn("OCR Image");
        tableModel.addColumn("OCR Text");
        tableModel.addColumn("Corrected Text");
        
        for (ImageText imageText : model.getImages()) {
            Object[] object = new Object[3];
            object[0] = imageText.getImage();
            object[1] = imageText.getOcrText();
            object[2] = imageText.getCorrectedText();
            tableModel.addRow(object);
        }
        
        JTable table = new JTable(tableModel);
        table.getColumnModel().getColumn(0).setPreferredWidth(220);
        table.getColumnModel().getColumn(1).setPreferredWidth(200);
        table.getColumnModel().getColumn(2).setPreferredWidth(200);
        
        table.setDefaultRenderer(BufferedImage.class, new ImageRenderer());
        table.setRowHeight(40);
        
        JScrollPane scrollPane = new JScrollPane(table);
        panel.add(scrollPane, BorderLayout.CENTER);
        panel.setPreferredSize(new Dimension(670, panel.getPreferredSize().height));
        
        return panel;
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel(new FlowLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        
        JButton button = new JButton("Save Corrections");
        button.addActionListener(new ButtonListener());
        panel.add(button);
        
        return panel;
    }
    
    public class OCRTableModel extends DefaultTableModel {

        private static final long serialVersionUID = 1L;

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex < 3) {
                return getValueAt(0, columnIndex).getClass();
            } else {
                return JButton.class;
            }
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return (columnIndex == 2);
        }
        
    }
    
    public class ImageRenderer implements TableCellRenderer {
        
        JPanel panel = new JPanel(new FlowLayout());
        JLabel label = new JLabel();
        
        @Override
        public Component getTableCellRendererComponent(JTable table, 
                Object value, boolean isSelected, boolean hasFocus,
                int row, int column) {
            label.setIcon(new ImageIcon((BufferedImage) value));
            panel.add(label);
            return panel;
        }
        
    }
    
    public class ButtonListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent event) {
            model.saveImages(tableModel);
        }
        
    }
    
    public class ImageTextModel {
        
        private final List<ImageText> images;
        
        public ImageTextModel() {
            this.images = new ArrayList<>();
            
            // This is where you would read the OCR images and OCR text from your
            // file system and add the information to the List. I generated OCR images to
            // make the GUI look more realistic.
            
            String name = "John Smith";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "George Washington";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "John Adams";
            images.add(new ImageText(createBufferedImage(name), name));
            name = "Thomas Jefferson";
            images.add(new ImageText(createBufferedImage(name), name));
        }
        
        private BufferedImage createBufferedImage(String text) {
            BufferedImage image = new BufferedImage(200, 30, BufferedImage.TYPE_INT_RGB);
            
            Graphics2D g2d = (Graphics2D) image.getGraphics();
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
            g2d.setColor(Color.BLACK);
            
            int pointSize = 20;
            Font font = new Font("Arial", Font.BOLD, pointSize);
            FontMetrics fm;
            Rectangle2D r;
            
            do {
                g2d.setFont(font);
                fm = g2d.getFontMetrics();
                r = fm.getStringBounds(text, g2d);
                pointSize -= 2;
                font = font.deriveFont((float) pointSize);
            } while (image.getWidth() < r.getWidth());
            
            int x = (image.getWidth() - (int) r.getWidth()) / 2;
            int y = (image.getHeight() - (int) r.getHeight()) / 2 + fm.getAscent();
            g2d.drawString(text, x, y);
            
            g2d.dispose();
            
            return image;
        }
        
        public void saveImages(OCRTableModel tableModel) {
            for (int row = 0; row < tableModel.getRowCount(); row++) {
                String correctedText = (String) tableModel.getValueAt(row, 2);
                System.out.println(correctedText);
                
                // Here's where you would write the corrected text to a file
                if (!correctedText.isBlank()) {
                    images.get(row).setCorrectedText(correctedText);
                }
            }
        }

        public List<ImageText> getImages() {
            return images;
        }
        
    }
    
    public class ImageText {
        
        private final BufferedImage image;
        
        private final String ocrText;
        private String correctedText;

        public ImageText(BufferedImage image, String ocrText) {
            this.image = image;
            this.ocrText = ocrText;
            this.correctedText = "";
        }

        public String getCorrectedText() {
            return correctedText;
        }

        public void setCorrectedText(String correctedText) {
            this.correctedText = correctedText;
        }

        public String getOcrText() {
            return ocrText;
        }

        public BufferedImage getImage() {
            return image;
        }
        
    }

}