Swing, рисование в jFrame без переопределения paint()

 
 
 
Сообщения:3
Я уже второй день пытаюсь хоть как-то нарисовать что-то в JFrame. Ничего не получается.
Моя логика такая: создаю JFrame, задаю его размер, делаю его видимым.
Далее множество вариантов пробовал:
public class first extends JFrame {
	public static void main(String[] args) 
	{
JFrame f = new JFrame();
f.setSize(640,480);
Canvas c = new Canvas();
f.add(c); 
f.setVisible(true);
Graphics g = c.getGraphics(); 
g.fillRect(100,100,100,100);
c.paint(g);
}}


Пробовал переопределять метод paint() и тоже потерпел провал. Пробовал использовать getContentPane(); - тоже потерпел фейл. Максимум чего я смог добиться - это изменить цвет фона окна.

Теперь собственно сам вопрос:
почему приведенный мною пример НЕ работает?
Моя логика тут бессильна.
Ведь все логично: мы создаем фрейм. Потом создаем область, в которой можно рисовать (сам Canvas). Потом рисуем в этой области прямоугольник. Затем создаем объект Graphic и передаем в него получившуюся картину, которую затем, при помощи метода paint() вырисовываем.
Где тут ошибка???
Мне очень нужна простая реализация этого примера, очень желательно без использования переопределения painta() и потоков... (если это возможно).
 
 
Сообщения:1240
http://www.javatalks.ru/ftopic7663/Image-+-JScrollPane

Тут не совсем по теме, но как рисовать - показано.
 
 
Сообщения:6977
KopZone:
Мне очень нужна простая реализация этого примера, очень желательно без использования переопределения painta() и потоков... (если это возможно).


Вы не можете рисовать без переопределения paint. По принципам организации отрисовки компонент в Java. Компонента в любой момент может получить сообщение, которое вызовет ее перерисовку. Перерисовка осуществляется в методе paint. Таким образом, компонента нарисует на себе только то, что умеет рисовать ее метод paint. У Canvas он умеет только очищать компоненту. Если Вы хотите рисовать что-то еще - у Вас нет других вариантов кроме переопределения paint.

Там не всё так страшно, как кажется. Вот это почитайте: http://www.skipy.ru/technics/gui_int.html

С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
 
 
Сообщения:3
Спасибо за ответы! наконец то поучилось нарисовать в фрейме хоть что-то! Правда я не до конца понял как это получилось: приходилось в main() создавать экземпляр класса, только в этом случае отрисовывался rect.
Непонятно разделение методов рисования на paint и componentPaint. Вроде бы оба метода определены экземплярами супер-класса, но Paint никак не удается заставить работать. Не могу понять для чего он нужен.
Что конкретно отрисовывает метод Paint?
 
 
Сообщения:3
У меня родился новый вопрос.
Получилось заставить квадратик двигаться. Я потратил на это около недели. Вот так вот, все вроде просто, а на деле мучиться приходится.
Вот код:
public class first extends JFrame implements KeyListener, Accessible   {
	int x = 0, y = 0;
	JFrame F;
	Window w;
	
	
	public first()
	{
		//F = new JFrame();	
		
		setSize(640,480);
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		w = new Window(x,y);
		add(w);
		
		setVisible(true);
		
	}


public static void main (String[] args) 
	{
	
	first f = new first();
	f.addKeyListener(f);
	}





@Override
public void keyPressed(KeyEvent e) {
	// TODO Auto-generated method stub
char key = e.getKeyChar();
switch (key) {
case 'w':
	y = y - 10;
	w.setLocation(x, y);
	
	break;
case 's':
	y = y + 10;
	w.setLocation(x, y);
	
	break;
case 'a':
	x = x - 10;
	w.setLocation(x, y);
	
	break;
case 'd':
	x = x + 10;
	w.setLocation(x, y);
	
	break;
}
}


@Override
public void keyReleased(KeyEvent e) {
	// TODO Auto-generated method stub
	
}




@Override
public void keyTyped(KeyEvent e) {
	// TODO Auto-generated method stub
	
}

}//конец класса
и класс, рисующий объект


public class Window extends JPanel {
	int X=0, Y=0;
	
	public Window(int x, int y)
	{
		X = x;
		Y = y;
		setSize(100,100);
		
		setVisible(true);
	}
	public void update(Graphics g){
		paintComponent(g);
	}
	protected void paintComponent(Graphics g)
	{
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D)g;
		
		g2d.setColor(Color.yellow);
		g2d.fillRect(X, Y, 100, 100);
	}
	
}


Теперь сам вопрос: могу ли я использовать KeyListner через мой класс Window? У меня не получается. Получилось только прослушивать фрейм, а добавленные в него компоненты прослушивать не получается. Как решить этот вопрос?
 
 
Сообщения:6977
Сообщения KeyListener-у идут только в том случае, когда компонента в фокусе. Если хотите отлавливать в принципе все нажатия в окне - это делается через ActionMap/InputMap. Вот тут рассказывается теория: http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html

А реализуется где-то так:

package ru.skipy.tests;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

/**
 * ComponentMoveTest
 *
 * @author Eugene Matyushkin aka Skipy
 * @since 16.10.12
 */
public class ComponentMoveTest extends JFrame {

    private Rect rect;

    private static final int STEP = 10;
    private static final String ACTION_UP = "up";
    private static final String ACTION_DOWN = "down";
    private static final String ACTION_LEFT = "left";
    private static final String ACTION_RIGHT = "right";

    public ComponentMoveTest() {
        super("Component Move Test");
        JPanel cp = new JPanel(null);
        rect = new Rect();
        rect.setBackground(Color.red);
        cp.add(rect);
        JRootPane rp = getRootPane();
        // регистрируем обработчики действий
        rp.getActionMap().put(ACTION_LEFT, new LeftMoveAction());
        rp.getActionMap().put(ACTION_RIGHT, new RightMoveAction());
        rp.getActionMap().put(ACTION_UP, new UpMoveAction());
        rp.getActionMap().put(ACTION_DOWN, new DownMoveAction());
        // получаем InputMap самого верхнего уровня (у root pane) 
        // для случая, когда фокус где-то в окне
        InputMap im = rp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        // связываем нажатия клавиш с зарегистрированными действиями
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), ACTION_LEFT);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), ACTION_RIGHT);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), ACTION_UP);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), ACTION_DOWN);
        setContentPane(cp);
        setSize(800, 600);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        rect.requestFocus();
    }

    public static void main(String[] args) {
        new ComponentMoveTest().setVisible(true);
    }

    private class UpMoveAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            rect.setLocation(rect.getX(), rect.getY() - STEP);
        }
    }

    private class DownMoveAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            rect.setLocation(rect.getX(), rect.getY() + STEP);
        }
    }

    private class LeftMoveAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            rect.setLocation(rect.getX() - STEP, rect.getY());
        }
    }

    private class RightMoveAction extends AbstractAction {
        @Override
        public void actionPerformed(ActionEvent e) {
            rect.setLocation(rect.getX() + STEP, rect.getY());
        }
    }

    private class Rect extends JPanel {
        public Rect() {
            setSize(100, 100);
            setOpaque(true);
        }
    }
}

С уважением,
Евгений aka Skipy
www.skipy.ru
P.S. Я НЕ решаю задачи ЗА других!
 
 
Сообщения:36
Вот это ты намудрил -_-
Слушай, напиши мне - посмотрим что и как. тут переписываться не понятно и долго, решение нашли вроде уже. Но, если нужны будут помощь и кооператив по прочим вопросам - сообщи. Потому что этот код - ппц, еще и неделю на него ушло.

KiraLis39
 
Модераторы:Нет
Сейчас эту тему просматривают:Нет