pagrippa:
1º Como é possível usar métodos da classe Graphics, por exemplo o método drawLine, se no código abaixo não esta sendo criado um objeto Graphics? Pelo menos não da maneira que eu aprendi até agora, que é usando new.
O new é usado em algum momento, mas não é e nem deve ser responsabilidade sua. Quem vai criar um objeto Graphics, que por sua vez vai estar "amarrado" ao SO é a JVM, não você. Na verdade nem é um Graphics que é criado, mas sim um Graphics2D (que estende Graphics), que por sua vez, varia de implementação para implementação da JVM, afinal, no Windows o "motor gráfico" é acessado de uma forma, enquanto no Linux é de outra. Esse objeto que é criado nos bastidores é passado para o método paintComponent (herdado de JComponent), que por sua vez é implementado em um JPanel com o objetivo de desenhar um painel. Aqui já estamos entrando na segunda dúvida...
pagrippa:
2º Não entendi a instrução super. Para mim, parece que ela faz com que, na linha super.paintComponent( g ), quando esse mesmo método da classe DrawLine for chamado, o método da classe JPanel fará com que seja executado de maneira correta, por eu estar ao mesmo tempo criando instruções nesse método. Ta muito errado isso?
Como o método paintComponent é usado para desenhar o componente, quando você estende um JPanel que você vai desenhar alguma coisa, vc precisa fornecer uma implementação nova para o método paintComponent, sobrescrevendo-o. Legal, mas e o super? A chamada super.paintComponent quer dizer que antes de mais nada, deve-se chamar o método paintComponent da superclasse, permitindo que haja uma chance do desenho padrão de um JPanel ser feito. Ou seja, primeiro vc garante que o painel padrão seja desenhado e então você desenha o que quiser nele. Apesar de você poder usar diretamente o objeto Graphics (na verdade é um Graphics2D) que é passado para o método paintComponent, é recomendado que você faça uma cópia do contexto gráfico original para que caso você precise executar alguma transformação no contexto (por exemplo, fazer uma translação nas coordenadas ou rotacionar o contexto) para que essa transformação não seja propagada a outros componentes que podem talvez usarem o mesmo objeto Graphics para se desenharem.
Como eu disse, se não forem feitas transformações, não precisa criar uma cópia do contexto, mas vai que um dia vc decide usar o método translate para mudar a origem do sistema de coordenadas. Ai você pode ter problemas caso algum outro componente use o mesmo objeto Graphics para se desenhar, pois o que antes era (0;0) (canto superior esquerdo), agora pode ser (-20;-20) caso tenha feito uma translação para (20;20). Eu normalmente só crio um novo contexto se eu tiver certeza que vou fazer alguma transformação, mas por via das dúvidas, o recomendado é sempre criar uma cópia do contexto. Atualizei seu código para refletir isso.
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawPanel extends JPanel {
// desenhando ESTE painel
public void paintComponent( Graphics g ) {
// primeiro garante o desenho padrão do painel
super.paintComponent( g );
// cria uma cópia do contexto gráfico
Graphics newG = g.create();
// hora de desenhar :D (note o uso da cópia do contexto)
int widht = getWidht(); //largura total
int height = getHeight(); //altura total
// usa a cópia do contexto para desenhar
newG.drawLine( 0, 0, widht, height ); //desenha uma linha a partir do canto superior esquerdo até o inferior direito
newG.drawLine( 0, height, widht, 0 ); //desenha uma linha a partir do canto inferior esquerdo ate o superior direito
// libera a cópia do contexto gráfico
newG.dispose();
} //fim do método paintComponent
} //fim da classe DrawPanel