问题摘要: 我使用Netbeans 7.2.1为在Windows 7(Java版本1.8.0_40)上开发的Java Swing / AWT程序生成.JAR文件,这有助于收集用户从屏幕上手写。它在Windows 7笔记本电脑上运行良好,但由于某些原因,仅在Windows 8.1平板电脑(Java版本1.8.0_45)上的屏幕特定区域捕获手写数据。有人可以告诉我为什么会这样吗?
详情:我要求收集在线手写样本(即使用钢笔/手写笔和书写表面从平板电脑等电子设备中获取的样本)进行分析
对于开发此类程序的新手,我在网上阅读了它并决定使用Java Swing / AWT工具包
一个人的笔迹由笔划组成,笔划又由点组成。我的目标是捕获: - 屏幕上某点的X坐标和Y坐标 - 创建这一点的时间戳 - 笔画的开始时间,结束时间和颜色(颜色不太重要)
为此,我在Windows 7 Home Basic操作系统上使用带有Java 1.8.0_40的Netbeans 7.2.1 IDE编写了以下程序
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package handwritingsamplerawt;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class HandwritingSamplerAWT {
static JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
CreateAndShowGUI();
}
});
}
private static void CreateAndShowGUI() {
frame = new JFrame("Writing Surface v0.1");
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.RIGHT));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.LIGHT_GRAY);
frame.pack();
frame.add(new MyPanel());
frame.setVisible(true);
}
}
class MyPanel extends JPanel{
private int x,y;
static int strokeIndex;
private long reducedMillis;
private ArrayList<StrokeInfo> strokes;
private JButton btnSave;
public MyPanel() {
MyPanel.strokeIndex=0;
this.reducedMillis = 1435800000000L;
this.strokes = new ArrayList<>();
this.btnSave = new JButton("SAVE SAMPLE");
this.btnSave.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
WriteCoordinates();
}
});
this.add(this.btnSave);
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
x=e.getX();
y=e.getY();
SaveCoordinates(x,y,"PRESSED");
repaint();
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
x=e.getX();
y=e.getY();
SaveCoordinates(x,y,"DRAGGED");
repaint();
}
});
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
x=e.getX();
y=e.getY();
SaveCoordinates(x,y,"RELEASED");
repaint();
}
});
}
void SaveCoordinates(int xCoordinate, int yCoordinate, String actionIndicator){
try {
Calendar cal = Calendar.getInstance();
Date currDate = cal.getTime();
double timeStamp=(double)(currDate.getTime()-reducedMillis);
PointInfo pointObj = new PointInfo(xCoordinate, yCoordinate, timeStamp);
switch (actionIndicator) {
case "PRESSED":
StrokeInfo newStroke = new StrokeInfo();
newStroke.points.add(pointObj);
strokes.add(newStroke);
break;
case "DRAGGED":
strokes.get(strokeIndex).points.add(pointObj);
break;
case "RELEASED":
strokeIndex+=1;
break;
}
} catch (Exception ex){
String errMsg = ex.getMessage();
System.out.println(errMsg);
}
}
void WriteCoordinates() {
try {
Calendar cal = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String currTimeString = dateFormat.format(cal.getTime());
DecimalFormat decFormat = new DecimalFormat("#");
decFormat.setMaximumFractionDigits(2);
FileWriter writer = new FileWriter("D:\\HandwritingCaptures\\HandwritingText\\"+currTimeString+".txt");
SetStrokeAttributes(strokes);
ListIterator<PointInfo> pointItr;
if (strokes.isEmpty()==false) {
for (int index = 0; index < strokeIndex; index++) {
writer.write(strokes.get(index).colour);
writer.append('\t');
writer.write(decFormat.format( strokes.get(index).startTime));
writer.append('\t');
writer.write(decFormat.format( strokes.get(index).endTime));
writer.append('\n');
pointItr = strokes.get(index).points.listIterator();
while (pointItr.hasNext()) {
PointInfo currPoint = pointItr.next();
writer.write(String.valueOf(currPoint.x));
writer.append('\t');
writer.write(String.valueOf(currPoint.y));
writer.append('\t');
writer.write(decFormat.format(currPoint.timestamp));
writer.append('\n');
}
writer.append('#');
writer.append('\n');
}
}
writer.close();
SaveScreenshot("D:\\HandwritingCaptures\\Screenshots\\"+currTimeString+".png");
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
void SetStrokeAttributes(ArrayList<StrokeInfo> strokeList) {
double startTime, endTime;
String colour;
StrokeInfo tmpStroke;
ArrayList<PointInfo> points;
if (strokeList.isEmpty() == false) {
for (int index = 0; index < strokeList.size(); index++) {
tmpStroke = strokeList.get(index);
points = tmpStroke.points;
tmpStroke.colour = "black";
tmpStroke.startTime=points.get(0).timestamp;
tmpStroke.endTime=points.get(points.size()-1).timestamp;
strokeList.set(index, tmpStroke);
}
}
}
void SaveScreenshot(String imgFilePath){
try {
Rectangle screenRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
BufferedImage capture = new Robot().createScreenCapture(screenRect);
ImageIO.write(capture, "png", new File(imgFilePath));
} catch (IOException | AWTException ex) {
System.out.println(ex.getMessage());
}
}
public Dimension getPreferredSize() {
return new Dimension(1366,768);
}
protected void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(Color.BLACK);
g.drawLine(x, y, x, y);
}
}
class PointInfo {
int x,y;
double timestamp;
public PointInfo(int px, int py, double ts) {
this.x=px;
this.y=py;
this.timestamp=ts;
}
}
class StrokeInfo {
ArrayList<PointInfo> points;
double startTime, endTime;
String colour;
public StrokeInfo() {
points= new ArrayList<>();
}
}
我使用IDE本身生成了.jar文件(Project Properties-&gt; Build-&gt; Packaging-&gt; Compress JAR file)
然后将.jar文件复制到配备JRE 1.7.0.800和Windows 7 Pro OS(32位)的HP EliteBook 2730P笔记本电脑,在那里它可以很好地从屏幕的所有区域收集手写笔划
但是当我将同样的.jar复制到配备JRE 1.8.0_45和Windows 8.1(64位)的HP Elite x2 1011 G1平板电脑并运行它时,我发现它奇怪地仅从特定区域捕获手写笔输入。屏幕 - 更具体地说是右上角。它对其他领域完全没有回应
有人可以帮我理解为什么会这样吗?会在这里张贴几张截图,但我的低声望使我无法这样做。
其他想法:使用.NET或Java FX开发此类工具以在Windows 8.1环境中使用会更好吗?
答案 0 :(得分:1)
您的面板似乎有一个固定的尺寸:
return new Dimension(1366,768);
平板电脑的分辨率是否大于此值?
编辑:
这应该有所帮助:
private static void CreateAndShowGUI() {
frame = new JFrame("Writing Surface v0.1");
// Using the default BorderLayout here.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.LIGHT_GRAY);
frame.getContentPane().add(new MyPanel(), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
然而,您的布局仍然存在问题,例如“保存”按钮跳转。你应该看看这个教程:
https://docs.oracle.com/javase/tutorial/uiswing/layout/index.html
答案 1 :(得分:0)
在运行时看到.jar文件的行为时,问题可能与硬编码维度有关的事实变得清晰
平板电脑的分辨率更高(1920 x 1080像素 - 通过右键单击桌面检查屏幕分辨率),而不是我最初运行该程序的机器(1366 x 768像素)。朝向右上角的可写区域的尺寸实际上与硬编码尺寸相符
因此,我以下列方式修改了重写方法 getPreferredSize():
public Dimension getPreferredSize() {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
return new Dimension((int)screenSize.getWidth(),(int)screenSize.getHeight());
}
这会使首选大小的组件占据执行.jar的设备屏幕的有效高度和宽度。这很重要,因为取决于所使用的布局管理器通过它来处理上述方法确实不同
&#34;保存样本&#34;按钮间歇性地似乎仍然将其图像(不可点击)投射到屏幕的其他区域 - 这可能与布局管理器处理UI组件有关。一旦找到解决方案,也应该为该问题添加编辑