Как сделать холст с Swing?
Я пытаюсь сделать редактор красок с Java, в котором у меня есть панель инструментов с объектами, которые я хотел бы вставить в холст. Я использую компоненты Swing для создания графического интерфейса, но когда я искал способ сделать холст, я нашел только холст класса от AWT.
Есть ли способ сделать что-то похожее на холст с Swing? (например, JPanel?) Я прочитал, что использование холста класса из AWT с графическим интерфейсом, сделанным с помощью swing, будет работать неправильно, это правда?
Ответы
Ответ 1
Чтобы создать пользовательский "холст" в качелях, вы обычно пишете подкласс JPanel
. Затем вы должны перезаписать метод protected paintComponent(Graphics g)
JPanel
.
В методе paint вы можете вызвать методы на объекте Graphics
для фактического рисования на JPanel
.
Как всегда, в учебниках по Java есть отличная ссылка, чтобы вы начали.
Ответ 2
Возможно, вы захотите сделать подкласс JPanel
и реализовать свой собственный способ рисования компонентов, которые вы хотите нарисовать на панель.
Базовый подход, вероятно, будет по линии присвоения MouseListener
подкласса JPanel
, а затем реализовать функции рисования.
Основная идея может быть чем-то вроде строки:
class MyCanvas extends JPanel implements MouseListener
{
Image img; // Contains the image to draw on MyCanvas
public MyCanvas()
{
// Initialize img here.
this.addMouseListener(this);
}
public void paintComponent(Graphics g)
{
// Draws the image to the canvas
g.drawImage(img, 0, 0, null);
}
public void mouseClicked(MouseEvent e)
{
int x = e.getX();
int y = e.getY();
Graphics g = img.getGraphics();
g.fillOval(x, y, 3, 3);
g.dispose();
}
// ... other MouseListener methods ... //
}
Приведенный выше пример неполный (и не проверенный - он определенно не будет компилироваться), но он дает представление о том, как реализовать класс MyCanvas
, в котором пользователь может щелкнуть и нарисовать круги.
Объект img
используется для хранения изображения холста. Метод paintComponent
используется для рисования объекта img
на холсте. В методе mouseClicked
объект Graphics
, связанный с img
, извлекается для fillOval
на изображение.
Поскольку каждый из требований заключается в том, чтобы вставлять изображения на холст, может быть хорошей идеей провести несколько Image
, которые вы хотите вставить в холст. Возможно, что-то по линии:
Image[] myImages; // Used to store images to paint to screen.
Затем в подпрограмме для рисования изображения на img
, сохраненного в MyCanvas
:
g.drawImage(myImage[INDEX_OF_DESIRED_IMAGE], 0, 0, null);
Используя drawImage
метод Graphics
, другой Image
можно нарисовать на Image
s.
Что касается вопроса о AWT и Swing, да, это правда, что вы не хотите смешивать компоненты с AWT и Swing, поскольку они отличаются тем, как они отображают компоненты GUI. AWT основан на тяжеловесных компонентах, что означает их собственное окно для рисования GUI, в то время как Swing основан на легких компонентах, что означает, что графический интерфейс рисован самой Java без использования собственных компонентов.
Хорошее руководство по разнице AWT и Swing представлено в картине в AWT и Swing из Sun.
Ответ 3
Просто подкласс JComponent
.
JPanel
является неприемлемым классом. Это часто предлагается, поскольку он, как представляется, имеет setOpaque(true)
, вызываемый на нем автоматически. На самом деле PL & F, который делает это, и действительно ли это происходит, зависит от реализации и поставщика.
Canvas
- тяжеловесный компонент. То есть он управляется базовой системой окон. В результате он обычно будет нарисован поверх компонентов Swing без учета z-порядка или отсечения (помещение его в панель прокрутки приведет к нечетному поведению).
Ответ 4
Возможно, вы захотите посмотреть на API Minueto. Это очень простая в использовании графика api, и вы можете комбинировать прослушивание Java-событий с ней, чтобы обеспечить возможность рисования.
http://minueto.cs.mcgill.ca/