package zhuye;
|
|
import javax.swing.*;
|
import java.awt.*;
|
import java.awt.IllegalComponentStateException;
|
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowEvent;
|
|
import gecaoji.Device;
|
|
/**
|
* 手持绘制边界的逐点采集对话框。
|
*/
|
class HandheldBoundaryCaptureDialog extends JDialog {
|
private final Shouye owner;
|
private final JLabel instructionLabel;
|
private final JButton confirmButton;
|
private final JButton finishButton;
|
private final JPanel mapPanel;
|
private final Timer statusMonitor;
|
private final Color enabledColor;
|
private int nextPointIndex = 1;
|
|
HandheldBoundaryCaptureDialog(Window parent, Shouye owner, JPanel mapPanel, Color enabledColor) {
|
super(parent, "手持采集边界", ModalityType.APPLICATION_MODAL);
|
this.owner = owner;
|
this.mapPanel = mapPanel;
|
this.enabledColor = enabledColor != null ? enabledColor : new Color(46, 139, 87);
|
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
setResizable(false);
|
setAlwaysOnTop(true);
|
|
instructionLabel = new JLabel("", SwingConstants.CENTER);
|
instructionLabel.setFont(new Font("微软雅黑", Font.BOLD, Math.max(11, (int) Math.round(16 * 0.7))));
|
instructionLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
|
updateInstructionText();
|
|
confirmButton = new JButton("确定");
|
confirmButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
confirmButton.setFocusPainted(false);
|
confirmButton.setOpaque(true);
|
confirmButton.setBorder(BorderFactory.createEmptyBorder(8, 18, 8, 18));
|
confirmButton.addActionListener(e -> handleConfirm());
|
|
finishButton = new JButton("结束");
|
finishButton.setFont(new Font("微软雅黑", Font.BOLD, 14));
|
finishButton.setFocusPainted(false);
|
finishButton.setOpaque(true);
|
finishButton.setBackground(new Color(255, 153, 0));
|
finishButton.setForeground(Color.WHITE);
|
finishButton.setEnabled(false);
|
finishButton.setVisible(false);
|
finishButton.setBorder(BorderFactory.createEmptyBorder(8, 18, 8, 18));
|
finishButton.addActionListener(e -> handleFinish());
|
|
buildLayout();
|
alignButtonSizes();
|
getRootPane().setDefaultButton(confirmButton);
|
pack();
|
Dimension initialSize = getSize();
|
if (initialSize != null && initialSize.width > 0) {
|
setSize(new Dimension(initialSize.width * 2, initialSize.height));
|
}
|
adjustPreferredSize();
|
positionNearMap();
|
updateActionButtons();
|
SwingUtilities.invokeLater(confirmButton::requestFocusInWindow);
|
|
statusMonitor = new Timer(400, e -> refreshStatus());
|
statusMonitor.setRepeats(true);
|
statusMonitor.start();
|
refreshStatus();
|
|
addWindowListener(new WindowAdapter() {
|
@Override
|
public void windowClosing(WindowEvent e) {
|
dispose();
|
}
|
});
|
}
|
|
private void buildLayout() {
|
JPanel content = new JPanel(new BorderLayout());
|
content.setBorder(BorderFactory.createEmptyBorder(20, 24, 20, 24));
|
content.add(instructionLabel, BorderLayout.CENTER);
|
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 16, 0));
|
buttonPanel.add(confirmButton);
|
buttonPanel.add(finishButton);
|
content.add(buttonPanel, BorderLayout.SOUTH);
|
|
setContentPane(content);
|
}
|
|
private void adjustPreferredSize() {
|
Dimension size = getSize();
|
if (size.height > 0) {
|
int adjustedHeight = Math.max((int) (size.height * 0.7), 160);
|
setSize(new Dimension(size.width, adjustedHeight));
|
}
|
}
|
|
private void positionNearMap() {
|
final int margin = 16;
|
if (owner != null && owner.isShowing()) {
|
try {
|
Point ownerLocation = owner.getLocationOnScreen();
|
Dimension ownerSize = owner.getSize();
|
Dimension dialogSize = getSize();
|
int x = ownerLocation.x + (ownerSize.width - dialogSize.width) / 2;
|
int y = ownerLocation.y + ownerSize.height - dialogSize.height - margin;
|
if (x < ownerLocation.x + margin) {
|
x = ownerLocation.x + margin;
|
}
|
if (y < ownerLocation.y + margin) {
|
y = ownerLocation.y + margin;
|
}
|
setLocation(x, y);
|
return;
|
} catch (IllegalComponentStateException ignored) {
|
// fallback handled below
|
}
|
} else if (mapPanel != null && mapPanel.isShowing()) {
|
try {
|
Point mapLocation = mapPanel.getLocationOnScreen();
|
Dimension mapSize = mapPanel.getSize();
|
Dimension dialogSize = getSize();
|
int x = mapLocation.x + (mapSize.width - dialogSize.width) / 2;
|
int y = mapLocation.y + mapSize.height - dialogSize.height - margin;
|
setLocation(x, y);
|
return;
|
} catch (IllegalComponentStateException ignored) {
|
// fallback handled below
|
}
|
}
|
setLocationRelativeTo(owner);
|
}
|
|
private void handleConfirm() {
|
if (!confirmButton.isEnabled()) {
|
return;
|
}
|
int count = owner.captureHandheldBoundaryPoint();
|
if (count <= 0) {
|
return;
|
}
|
nextPointIndex = count + 1;
|
updateInstructionText();
|
updateActionButtons();
|
}
|
|
private void handleFinish() {
|
if (owner.finishHandheldBoundaryCapture()) {
|
dispose();
|
}
|
}
|
|
@Override
|
public void dispose() {
|
if (statusMonitor != null) {
|
statusMonitor.stop();
|
}
|
super.dispose();
|
owner.handheldBoundaryCaptureDialogClosed(this);
|
}
|
|
private void refreshStatus() {
|
boolean hasFix = isFixQualityAvailable();
|
boolean hasValidPosition = hasFix && hasValidCurrentPosition();
|
boolean duplicate = hasValidPosition && isDuplicateCurrentPosition();
|
boolean enabled = hasValidPosition && !duplicate;
|
confirmButton.setEnabled(enabled);
|
if (enabled) {
|
confirmButton.setBackground(enabledColor);
|
confirmButton.setForeground(Color.WHITE);
|
} else {
|
confirmButton.setBackground(new Color(200, 200, 200));
|
confirmButton.setForeground(new Color(130, 130, 130));
|
}
|
if (!hasFix) {
|
confirmButton.setToolTipText("当前定位质量不足,无法采集");
|
} else if (!hasValidPosition) {
|
confirmButton.setToolTipText("当前定位数据无效,请稍后再试");
|
} else if (duplicate) {
|
confirmButton.setToolTipText("当前坐标已采集,请移动到新的位置");
|
} else {
|
confirmButton.setToolTipText(null);
|
}
|
}
|
|
private boolean isDuplicateCurrentPosition() {
|
return owner != null && owner.isCurrentHandheldPointDuplicate();
|
}
|
|
private boolean hasValidCurrentPosition() {
|
return owner != null && owner.hasValidRealtimeHandheldPosition();
|
}
|
|
private void updateInstructionText() {
|
instructionLabel.setText("是否采集当前点" + nextPointIndex);
|
}
|
|
private void alignButtonSizes() {
|
Dimension confirmSize = confirmButton.getPreferredSize();
|
finishButton.setPreferredSize(confirmSize);
|
finishButton.setMinimumSize(confirmSize);
|
finishButton.setMaximumSize(confirmSize);
|
}
|
|
private void updateActionButtons() {
|
int totalPoints = owner != null ? owner.getHandheldCapturedPointCount() : 0;
|
boolean hasMinimumPoints = totalPoints >= 3;
|
finishButton.setVisible(hasMinimumPoints);
|
finishButton.setEnabled(hasMinimumPoints);
|
confirmButton.setVisible(true);
|
}
|
|
private boolean isFixQualityAvailable() {
|
Device device = Device.getGecaoji();
|
if (device == null) {
|
return false;
|
}
|
String status = device.getPositioningStatus();
|
if (status == null) {
|
return false;
|
}
|
return "4".equals(status.trim());
|
}
|
}
|