Итак, я думаю, что у вас есть фундаментальное недоразумение, как все хорошо работает в Swing.
У вас «есть» проблема с тем, как работает система управления макетами, как система окраски работает и как работает система координат
. Начнем с вашего компонента Dr
.
Кажется, вы хотите разработать перекрывающиеся компоненты, которые могут показывать дочерние компоненты ниже них , но вы используете setOpaque(true);
, что означает, что компонент не будет видеть через
Это ...
public void draw() {
if (buffer == null && width > 0 && height > 0) {
buffer = new BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_ARGB);
}
if (buffer == null) return;
Graphics g = buffer.getGraphics();
setBounds(0, 0, full_width, full_height);
Graphics2D g2d = (Graphics2D)g;
g2d.setBackground(Color.WHITE);
g2d.clearRect(0, 0, full_width, full_height);
g2d.setColor(new Color(255, 0, 80, 128));
g2d.fillRect(left, top, width, height);
System.out.println(left + ", " + top);
}
Кажется странным для меня. Вы определяете BufferedImage
размером width
на height
, но затем используйте full_width
и full_height
, чтобы заполнить его ... мне кажется, иметь смысл сделать это другим способом round
@Override
public void repaint() {
draw();
}
Хорошо, важный урок в Swing, вы не контролируете процесс рисования, поэтому не пытайтесь. Swing имеет хорошо документированный и хорошо проработанный процесс окраски, который обеспечивает четко определенные крючки, в которые вы можете вводить свою обычную картину (т.е. paintComponent
). Если вам нужно «управление», вам нужно взглянуть на использование функции BufferStrategy
, которая даст вам полный контроль, чтобы определить, что вы собственный процесс рисования.
Хорошо, так что ответ?
Ну, это не так прямо, потому что я не на 100% уверен, что понимаю, в чем проблема, которую вы пытаетесь решить.
Но давайте начнем с Dr
panel ...
public class Dr extends JPanel {
public Dr(int x, int y, int w, int h, int fw, int fh) {
left = x;
top = y;
width = w;
height = h;
full_width = fw;
full_height = fh;
setOpaque(false);
setBounds(x, y, fw, fh);
}
public void draw() {
if (buffer == null && width > 0 && height > 0) {
buffer = new BufferedImage(getWidth(), getHeight(), java.awt.image.BufferedImage.TYPE_INT_ARGB);
}
Graphics g = buffer.getGraphics();
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(255, 0, 80, 128));
g2d.fillRect(0, 0, width, height);
g2d.dispose();
}
@Override
public void paintComponent(Graphics g) {
draw();
g.drawImage(buffer, 0, 0, this);
g.setColor(Color.RED);
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
}
private BufferedImage buffer;
private int left;
private int top;
private int width;
private int height;
private int full_width;
private int full_height;
}
Итак, здесь я изменил его так, чтобы панель была помещена в позицию x
, y
, которую вы передаете конструктору, и будет иметь размер к свойствам fw
и fh
.
В методе draw
я затем создаю BufferedImage
, размер которого соответствует текущему размеру и краске компонента ... что когда-либо ... на основе свойства width
и height
... возникают вопросы о том, почему мы имеем размеры, но там есть ...
Затем буфер извлекается в верхнюю / левую позицию компонент, это важно, система координат Swing основана на самом компоненте, поэтому 0x0
всегда является верхним / левым углом c omponent, система координат не имеет ничего общего с родительским контейнером.
ps - Красный прямоугольник предназначен для отладки, вам он не нужен.
Затем я использую ...
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new JLayeredPane());
frame.add(new Dr(10, 10, 180, 180, 200, 200));
frame.add(new Dr(100, 100, 180, 180, 200, 200));
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
И вуаля, перекрывающиеся компоненты ...
Теперь, я настоятельно рекомендуем остановиться и продолжить чтение:
И, мое чувство кишки, вы, вероятно, действительно не хотите отдельных компонентов, то, что вы хотите, это один компонент, который может рисовать много буферов
Используйте литерал regex [MDN] :
var reg = /\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)/g;
Вы делаете две ошибки, когда используете RegExp
[MDN] :
/
не должны быть частью выражения Кроме того, модификаторы передаются как второй аргумент функции.
Итак, если вы хотите использовать RegExp
(который вы не используете в этом случае), эквивалент был бы следующим:
var reg = new RegExp("\\(\\s*([0-9.-]+)\\s*,\\s([0-9.-]+)\\s*\\)", "g");
(и теперь я понял, почему регулярные выражения являются более удобными)
Я всегда нахожу его полезно скопировать и пропустить выражение RegExp
в консоли и посмотреть его вывод. Принимая ваше исходное выражение, получаем:
/(s*([0-9.-]+)s*,s([0-9.-]+)s*)/g
, что означает, что выражения пытаются сопоставить /
, s
и g
буквально, а parens ()
по-прежнему рассматриваются как специальные символы .
Обновление: .match()
возвращает массив:
["(25.774252, -80.190262)", "(18.466465, -66.118292)", ... ]
, который, кажется, не очень полезен.
Вы должны использовать .exec()
[MDN] для извлечения чисел:
["(25.774252, -80.190262)", "25.774252", "-80.190262"]
Это нужно вызывать до тех пор, пока все строки не будут обрабатывается.
Пример:
var reg = /\(\s*([0-9.-]+)\s*,\s([0-9.-]+)\s*\)/g;
var result, points = [];
while((result = reg.exec(polygons)) !== null) {
points.push([+result[1], +result[2]]);
}
Это создает массив массивов, а унарный плюс (+
) преобразует строки в числа:
[
[25.774252, -80.190262],
[18.466465, -66.118292],
...
]
Конечно, если вы хотите, чтобы значения как строки, а не как числа, вы можете просто опустить +
.