【问题标题】:Automate placing a jTextField next to an ImageIcon自动将 jTextField 放置在 ImageIcon 旁边
【发布时间】:2021-05-23 20:56:49
【问题描述】:

我想自动将 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,它显示的是图像的路径而不是图像

【问题讨论】:

  • 很难回答你,因为你没有提供任何代码。是什么阻止你现在这样做?你以前写过 Swing 程序吗?你以前用过layout吗?你知道每个文本字段的图像来自哪里吗?
  • 欢迎来到 Stack Overflow。请通过tour 了解 Stack Overflow 的工作原理,并阅读How to Ask 了解如何提高问题的质量。然后edit你的问题包括你拥有的完整源代码作为minimal reproducible example,它可以被其他人编译和测试。请显示您尝试过的尝试以及您从尝试中得到的问题/错误消息。
  • 我不明白这个问题。 Swing 旨在与布局管理器一起使用。您可以轻松地为图像和文本文本字段创建 JPanel。然后将面板添加到父面板。
  • 我想要一个从包含图像的文件夹中自动创建的图像列表,并且在该列表前面我想要另一个根据其他列表创建的文本字段列表
  • “我想要一个从包含图像的文件夹中自动创建的图像列表”听起来你想要一个JList或JTable,for example

标签: java swing ocr


【解决方案1】:

简介

这是我想出的 GUI。

要使用此 GUI,您可以用鼠标选择要更正的第一行,然后在该行中键入更正后的文本。

按 Enter 键将光标放在下一行。您可以通过按 Enter 键跳过一行,而无需输入任何内容。

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

说明

当我创建 Swing GUI 时,我使用 model / view / controller (MVC) 模式。这种模式让我可以将关注点分开,一次只关注 GUI 的一个部分。

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

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

通常没有一个控制器类可以“统辖”它们。每个ActionListener 充当一个独立的控制器。

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

型号

我创建了两个模型类。 ImageText 类包含 OCR 图像、OCR 文本和更正后的文本。这样可以将更正分开,并允许更轻松地验证代码的正确性。

ImageTextModel 类拥有java.util.List 的ImageText 实例。由于您没有提供任何 OCR 图像示例,因此我从文本中创建了一些示例。您可以在此处读取 OCR 图像和 OCR 文本并将值放入 List。

查看

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

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

上面的JPanel 包含JTable。较低的JPanel 包含JButton。 ImageCellRenderer 类允许我在 JTable 中显示 BufferedImage。

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

控制器

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

代码

这是完整的可运行代码。我把所有的类都做成了内部类,这样我就可以将代码作为一个块发布。

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;
        }
        
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 2011-12-15
    • 1970-01-01
    • 2019-01-02
    • 1970-01-01
    • 2013-05-15
    相关资源
    最近更新 更多