【问题标题】:Allow user handwriten marking on images - Java, Swing允许用户在图像上手写标记 - Java、Swing
【发布时间】:2012-12-30 19:06:36
【问题描述】:

我正在使用 Java、Swing 开发一个应用程序。它将主要用于研究用于医学目的的五角星波形图。希望用户可以在图像上做笔记(大概类似于 Window 的油漆中使用的铅笔)。

请记住,每次用户加载图像时,都会附加以下鼠标运动侦听器(为了使图像可拖动以提高可用性):

public class DragMouseListener implements MouseMotionListener {

    JLabel jl;
    int imageX, imageY;

    public DragMouseListener(JLabel jlabel) {
        this.jl = jlabel;
        jl.addMouseMotionListener(this);
    }


    @Override
    public void mouseDragged(MouseEvent e) {
        updateImagePosition(e);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    private void updateImagePosition(MouseEvent e) {
        imageX = e.getX();
        imageY = e.getY();
        jl.setLocation(imageX, imageY);
    }
}

到目前为止,我什至无法接近实现它的方法,而且我在 Internet 上找不到任何有关该问题的参考资料。任何帮助(甚至是粗略的想法)将不胜感激。提前致谢。

尼克

【问题讨论】:

  • 您希望图像与文本一起永久更新,还是希望它与文本相关联...例如图层,您可以根据需要加载和更新?您希望文本是“手写”的还是足以让用户在图像上输入文本的能力??
  • 为回复干杯。保存包括自定义注释的图像的能力将是可取的。键入文本不起作用,但一些固定的解决方案可能就足够了(例如,提供一个圆形工具,允许用户圈出波形图的峰值)
  • here 引用的示例说明了几种基本的对象绘制技术。
  • "五角星波形图" 嗯?第一个唤起了医务人员的形象,第二个让我想起了女巫。 -- 我倾向于将图像和任何相关文本都存储在一个 Zip 文件中,以便以后可以对其进行重建、编辑和调整。当然提供“导出到标题 PNG” - 但要明确用户正在失去一些东西。作为旁白。你有什么问题?
  • 希望这个关于painting on an image的答案在某种意义上可能会有所帮助。

标签: java swing handwriting


【解决方案1】:

我尝试了您要求的DragMouseListener,但发现它非常不舒服,因此使用JInternal Frame 它工作正常(但您仍然可以在 JInternal Frame 中拖动图像,因为我实现了您的要求)。免手写,我使用了JEditorPane(如果你愿意,你可以添加手写的东西,但这会很乱)和可访问的父 JScrollPane,这样你就可以输入你想要的数量。

您可以轻松拖动 JInternal Frame:

注意:我为此使用了 NetBeans GUI Builder,并建议您也使用任何 GUI Builder,因为它使 打字工作轻松。

代码如下:

import java.awt.event.MouseEvent;

public class Move extends javax.swing.JFrame {

public Move() {
    initComponents();
}

@SuppressWarnings("unchecked")

private void initComponents() {

    jPanel1 = new javax.swing.JPanel();
    jInternalFrame1 = new javax.swing.JInternalFrame();
    jLabel1 = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    jEditorPane1 = new javax.swing.JEditorPane();
    jInternalFrame2 = new javax.swing.JInternalFrame();
    jLabel2 = new javax.swing.JLabel();
    jScrollPane2 = new javax.swing.JScrollPane();
    jEditorPane2 = new javax.swing.JEditorPane();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jPanel1.setBackground(new java.awt.Color(0, 0, 0));

    jInternalFrame1.setVisible(true);

    jLabel1.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images.jpg"))); // NOI18N
    jLabel1.setText("jLabel1");
    jLabel1.addComponentListener(new java.awt.event.ComponentAdapter() {
        public void componentMoved(java.awt.event.ComponentEvent evt) {
            jLabel1ComponentMoved(evt);
        }
    });
    jLabel1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
        public void mouseDragged(java.awt.event.MouseEvent evt) {
            jLabel1MouseDragged(evt);
        }
    });

    jScrollPane1.setViewportView(jEditorPane1);

    javax.swing.GroupLayout jInternalFrame1Layout = new javax.swing.GroupLayout(jInternalFrame1.getContentPane());
    jInternalFrame1.getContentPane().setLayout(jInternalFrame1Layout);
    jInternalFrame1Layout.setHorizontalGroup(
        jInternalFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jInternalFrame1Layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(jInternalFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel1, 0, 0, Short.MAX_VALUE))
            .addContainerGap())
    );
    jInternalFrame1Layout.setVerticalGroup(
        jInternalFrame1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jInternalFrame1Layout.createSequentialGroup()
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE)
            .addContainerGap())
    );

    jInternalFrame2.setVisible(true);

    jLabel2.setIcon(new javax.swing.ImageIcon("E:\\untitled.png")); // NOI18N
    jLabel2.setText("jLabel2");

    jScrollPane2.setViewportView(jEditorPane2);

    javax.swing.GroupLayout jInternalFrame2Layout = new javax.swing.GroupLayout(jInternalFrame2.getContentPane());
    jInternalFrame2.getContentPane().setLayout(jInternalFrame2Layout);
    jInternalFrame2Layout.setHorizontalGroup(
        jInternalFrame2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jInternalFrame2Layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(jInternalFrame2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 222, Short.MAX_VALUE)
                .addComponent(jLabel2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 222, Short.MAX_VALUE))
            .addContainerGap())
    );
    jInternalFrame2Layout.setVerticalGroup(
        jInternalFrame2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jInternalFrame2Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jLabel2)
            .addContainerGap(40, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
    jPanel1.setLayout(jPanel1Layout);
    jPanel1Layout.setHorizontalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jInternalFrame1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(177, 177, 177)
            .addComponent(jInternalFrame2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(71, Short.MAX_VALUE))
    );
    jPanel1Layout.setVerticalGroup(
        jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
            .addGap(49, 49, 49)
            .addComponent(jInternalFrame1)
            .addGap(209, 209, 209))
        .addGroup(jPanel1Layout.createSequentialGroup()
            .addGap(31, 31, 31)
            .addComponent(jInternalFrame2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(166, Short.MAX_VALUE))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    pack();
}

private void jLabel1ComponentMoved(java.awt.event.ComponentEvent evt) {


}

private void jLabel1MouseDragged(java.awt.event.MouseEvent evt) {
   updateImagePosition(evt);

}
private void updateImagePosition(MouseEvent evt) {
   int imageX = evt.getX();
 int   imageY = evt.getY();
    jLabel1.setLocation(imageX, imageY);
}
public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new Move().setVisible(true);
        }
    });
}


private javax.swing.JEditorPane jEditorPane1;
private javax.swing.JEditorPane jEditorPane2;
private javax.swing.JInternalFrame jInternalFrame1;
private javax.swing.JInternalFrame jInternalFrame2;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JPanel jPanel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;


}

更新:

请参阅 @mKorbel 和 @trashgod 回答的 This 帖子,以使 JInternal 框架最小化/最大化和调整大小。很棒的答案。

【讨论】:

  • 非常感谢您解决所有麻烦并给我此代码。使用 jInternalFrame 似乎是一个更有吸引力和更强大的解决方案。我决定采用它,巧合的是,我也在使用 NetBeans GUI Builder。但是,我无法使内部框架可调整大小、最小化和可拖动。对于前两个,我使用其属性选项卡中提供的相应复选框,但它们不对应任何更改。特别是调整大小对于请求的功能至关重要。有什么想法吗?
  • 嗯,是的,我也遇到了这个问题。所以这是一个编码问题。任何方式都遵循stackoverflow.com/questions/6476525/…coderanch.com/t/432709/GUI/java/… 如果您找不到解决方案,请告诉我。我会尽力提供帮助。或者如果你发现了,就更新它..:) 和docs.oracle.com/javase/6/docs/api/javax/swing/…
猜你喜欢
  • 2020-03-11
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多