Archiwum kategorii 'Java' Category

13
maj

jEdit pod Ubuntu

jEdit w wersji na systemy uniksowe ma instalkę w postaci pliku .jar. Po instalacji również nie tworzę się żadne skróty, ikony ani pozycje w menu jak to ma miejsce w przypadku Windowsa. Dlatego krótki tutorial, jak ułatwić sobie życie.

Otwórz dowolny edytor tekstowy( np gEdit, Kate, vi etc ) i wpisz w nim taki kod:

#!/bin/bash
java -jar ../jedit/4.2/jedit.jar

Zapisz plik jako jedit.sh ( lub jakkolwiek chcesz inaczej, tylko trzymaj się konsekwentnie tego ). Ja to zrobiłem na pulpicie, żeby mieć go pod ręką zawsze. W konsoli nadaj odpowiednie uprawienia dla tego pliku poprzez komendę chmod, np tak:

chmod 0777 jedit.sh

Oczywiście musisz być w tym samym katalogu.

Teraz dwuklik na pliku jedit.sh na pulpicie spowoduje wyświetlenie monitu z pytanie co zrobić, wystarczy wybrać “Uruchom” i działa.

01
gru

Krótko o GridLayout

Pisząc małą apikację uznałem, że GridLayout w połączniu z BorderLayoutem będzie najlepszy - i przy okazji tego stworzyłem króciutki opis tego pierwszego managera layoutu.

Są trzy rodzaje konstruktorów:

  • bezparametrowy - jeden wiersz i jedna kolumna
  • przyjmujący dwa parametry - szerokość i wysokość w px
  • przyjmujący cztery parametry - dwa powyższe i dwa kolejne, które wyrażają odstępy w poziomie i w pionie pomiędzy elementami w px

Aby móc korzystać z tego managera trzeba na początku plik dać:

import java.awt.GridLayout;

Według mnie najlepszym zastosowaniem jest użycie tego managera jako fragmentu rozplanowania przestrzeniu w panelu i połączenie z innymi managerami. Można przykładowo zrobić rozkład ogólny za pomocą BorderLayout i środkowy element rozplanować poprzez GridLayout.

Tak jest zresztą chyba ze wszystkimi managerami - najlepiej je łączyć

23
wrz

Cytat dnia

ANSI C++ oferuje więcej typów strumien, niż kiedykolwiek będziesz potrzebował - np istream, ostream, iostream, ifsteam, ofsteam, fstream, wistream, wifstream, istrstream itd ( w sumie 18 klas ). Ale Java popadła juz w kompletną przesadę, oferując osobne klasy do buforowania, sprawdzania następnego w kolejce bajtu, swobodnego dostępu, formatowania tekstu, czy też binariów

Dodam od siebie, że Java ma ponad 60 takich klas :)

06
sie

Zabawy z czcionkami i Swing’iem

Kolejny prosty i edukacyjny programik napisany w Javie. Pojawiają się nowe komponenty w porównaniu do poprzedniej aplikacji. Plik główny:
package combo;
import javax.swing.*;
public class ComboTest {
public static void main(String[] args) {
ComboFrame frame = new ComboFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible( true );
}
}

Jeśli nie wiadomo co się tu dzieje to zapraszam do lektury wcześniejszego wpisu.
Plik ComboFrame.java:
package combo;
import javax.swing.*;
import java.awt.*;
public class ComboFrame extends JFrame{
public ComboFrame()
{
setTitle( “Lista czcionek w JComboBox” );
setSize( WIDTH, HEIGHT );
ComboPanel panel = new ComboPanel();
Container cont = getContentPane();
cont.add( panel );
}
private static final int WIDTH = 200;
private static final int HEIGHT = 300;
}

Zbyt wiele się tu też nie dzieje więc jak coś niejasne to patrz poprzedni wpis.
Plik ComboPanel.java:
package combo;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.event.*;
public class ComboPanel extends JPanel{
public ComboPanel()
{
// initialization
labelSize = new Rectangle( 10, 10, 100, 20 );
comboSize = new Rectangle( 10, 60, 100, 20 );
sliderSize = new Rectangle( 10, 110, 100, 20 );
// get fonts
String[] fontNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
// set layout
setLayout( null );
// create components
combo = new JComboBox( fontNames );
label = new JLabel( “Napis testowy” );
slider = new JSlider( 4, 20, 12 );
label.setBounds( labelSize );
combo.setBounds( comboSize );
combo.addActionListener( new ComboHandler() );
slider.setBounds( sliderSize );
slider.addChangeListener( new SliderHandler() );
// add components to panel
add( label );
add( combo );
add( slider );
}
private class ComboHandler implements ActionListener
{
public void actionPerformed( ActionEvent event )
{
String font = (String)combo.getSelectedItem();
label.setFont( new Font( font, Font.PLAIN, slider.getValue() ) );
}
}
private class SliderHandler implements ChangeListener
{
public void stateChanged( ChangeEvent event )
{
label.setFont( new Font( (String)combo.getSelectedItem(), Font.PLAIN, slider.getValue() ) );
}
}
private Rectangle labelSize;
private Rectangle comboSize;
private Rectangle sliderSize;
private JComboBox combo;
private JLabel label;
private JSlider slider;
}

Ten plik wymaga już wyjaśnienia. Na początku inicjalizujemy obiekty typu Rectangle, za chwilę się okaże po co. Następnie korzystamy z dostępnej już nam wiedzy jak pobrać czcionki dostępne w systemie.

Teraz pierwsza ważna rzecz:
// set layout
setLayout( null );

REZYGNUJEMY z menedżera rozkładu komponentów. Oznacza to tylko, że trzeba wszystkie elementy pozycjonować ręcznie, podając koordynaty ich lewej górnej krawędzi ( zaznaczam, że oś pozioma “rośnie” w prawo, a pionowa w DÓŁ! ). I po to właśnie inicjalizowaliśmy wcześniej obiektu typu Rectangle - mogą one być argumentami funkcji setBounds() dla komponentów. A dokładniej to ustalamy współrzędne lewej górnej krawędzi, potem szerokość i na końcu wysokość ( stąd 4 argumenty ).

Tworzenie komponentów raczej nie jest niezwykłym kodem, wyjaśnienia wymagać mogą jedynie parametry konstruktora JSlider. Są to odpowiednio:

  • wartość minimalna
  • wartość maksymalna
  • wartość domyślna

W dalszej części pojawia się nowy interface - ChangeListener. Implementjemy go, aby nasłuchiwać zdarzeń dla suwaka. ChangeListener posiada tylko jedną metodę do zaimplementowania i ma ona dokładnie takie samo działanie jak metoda actionPerformed() dla implementacji interface’u ActionListener. Celowo ten sam kod napisałem na dwa różne sposoby. Drugi sposób jest bardziej zwięzły i taki kod niektórym może wydawać się zagmatwany. W pierwszym przypadku dużo łatwiej jest odczytać i zrozumieć, co programista miał na myśli.

04
sie

Myszkoklikacz

Z pomocą książki dalej męczę naukę Javy. Oto co teraz zostało wypłodzone:

package myMouse;
import javax.swing.*;
public class MouseTest {
public static void main(String[] args) {
MouseFrame frame = new MouseFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setVisible(true );
}
}
Główna klasa programu. Tworzy obiekt MouseFrame, ustawia domyślną reakcję na zdarzenie zamknięcia i pokazuje ramkę.

Dalej plik MouseFrame.java:

package myMouse;
import javax.swing.*;
import java.awt.*;
public class MouseFrame extends JFrame{
public MouseFrame()
{
setTitle( “Test Myszki” );
setSize( WIDTH, HEIGHT );
//
MousePanel panel = new MousePanel();
Container cont = getContentPane();
cont.add( panel );
}
private static final int WIDTH = 600;
private static final int HEIGHT = 400;
}

Również bez cudów, podstawowe metody klasy JFrame w użyciu. Następnie powstaje obiekt klasy dziedziczącej po JPanel i dodany do ramki.

Następny plik MousePanel.java:

package myMouse;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
import java.awt.geom.*;
import java.awt.*;
public class MousePanel extends JPanel{
public MousePanel()
{
squares = new ArrayList();
current = null;
//add listeners
addMouseListener( new MouseHandler() );
addMouseMotionListener( new MouseMotionHandler() );
}
public void paintComponent( Graphics graph )
{
super.paintComponent( graph );
Graphics2D graph2D = (Graphics2D)graph;
for ( int i = 0; i < squares.size(); i++ )
graph2D.draw( (Rectangle2D)squares.get( i ) );
}
public Rectangle2D find( Point2D point )
{
for ( int i = 0; i < squares.size(); i++ )
{
Rectangle2D rect = (Rectangle2D)squares.get( i );
if ( rect.contains( point ) ) return rect;
}
return null;
}
public void add( Point2D point )
{
current = new Rectangle2D.Double( point.getX() - LENGTH/2, point.getY() - LENGTH/2, LENGTH, LENGTH );
squares.add( current );
}
public void remove( Rectangle2D rect )
{
if ( rect == null ) return;
if ( rect == current ) current = null;
squares.remove( rect );
repaint();
}
private class MouseHandler extends MouseAdapter
{
public void mousePressed( MouseEvent event )
{
current = find( event.getPoint() );
if ( current == null )
add( event.getPoint() );
repaint();
}
public void mouseClicked( MouseEvent event )
{
current = find( event.getPoint() );
if ( current != null && event.getClickCount() >= 2 )
remove( current );
repaint();
}
}
private class MouseMotionHandler implements MouseMotionListener
{
public void mouseMoved( MouseEvent event )
{
if ( find( event.getPoint()) == null )
setCursor( Cursor.getDefaultCursor() );
else
setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
}
public void mouseDragged( MouseEvent event )
{
if ( current != null )
{
current.setFrame( event.getX() - LENGTH/2, event.getY() - LENGTH/2, LENGTH, LENGTH );
repaint();
}
}
}
private ArrayList squares;
private Rectangle2D current;
private static final int LENGTH = 10;
}

Jak widać kodu jest tu sporo więcej i wymaga on szerszego komentarza.

Konstruktor inicjalizuje zmienne oraz przypisuje do panelu dwa listenery, obydwa dotyczą zdarzeń związanych z myszką. Dlaczego dwa? Otóż zwykle interesują nas zdarzenia dotyczące kliknięć myszki i tym zajmuje się klasa, który implementuje interface MouseListener. Jednak aby śledzić ruchy myszki potrzebna jest zdecydowanie większa wydajność ponieważ są one zdecydowanie częstsze niż kliknięcia ( w sumie to występują zwykle cały czas w trakcie działania aplikacji ). Stąd powstał drugi interface MouseMotionListener. Metoda find() klasy MousePanel sprawdza czy dany punkt ( który właśnie kliknęliśmy ) należy do jakiegoś prostokąta. Jeśli tak to zwraca ten obiekt ( prostokąt ) a jeśli nie - zwraca null. Wykorzystana jest tutaj przydatna metoda Rectangle2D.contains( Point ), dzięki której nie musimy ręcznie bawić się koordynatami prostokąta i punktu. Kolejne metody to add() i remove(), które odpowiednio dodają i usuwają prostokąt. Lista prostokątów znajduje się w obiekcie typu ArrayList z pakietu java.util.*

I teraz ważna rzecz. Dwie klasy PRYWATNE, które są naszymi listenerami ( słuchaczami ). Pierwsza z nich implementuje interface MouseListener, ale można powiedzieć pośrednio. Ponieważ interface ten zawiera więcej niż jedną metodą posiada klasę adaptacyjną, w której wszystkie te metody są zaimplementowane jako puste więc dziedzicząc przeciążamy tylko interesujące nas funkcje składowe. Klasa adaptacyjna w tym wypadku to MouseAdapter. W metodzie mousePressed() sprawdzamy czy kliknięcie nie nastąpiło wewnątrz prostokąta, jeśli nie to dodajemy prostokąt, który ma środek w punkcie klikniętym przez nas myszką. Metoda mouseClicked() sprawdzą z kolei czy kliknęliśmy dwukrotnie wewnątrz prostokąta, jeśli tak to usuwamy ten prostokąt.

Druga klasa prywatna odpowiada z obsługę zdarzeń ruchu myszką. Metoda mouseMoved() sprawdza gdzie jest kursor myszy - jeśli wewnątrz prostokąta to zmienia jego wygląd na krzyżyk, jeśli poza prostokątem to ustawia standardowy wygląd. Metoda mouseDragged() jak nazwa sugeruje odpowiada za ‘przeciąganie’. Przesuwa ona obecny prostokąt razem z kursorem myszki. Wykorzystana jest tu metoda setFrame( double x, double y, double width, double height ), która zmienia położenie i wielkość obiektu typu Rectangle2D. Po przeniesieniu należy odrysować panel wywołując metodę repaint().

Nie zamieszczam screenów programu bo nic ciekawego nie widać, program bardziej edukacyjny niż pożyteczny.

19
lip

Pobranie rozdzielczości ekranu

Aby pobrać rozdzielczość ekranu w Javie, trzeba użyć klasy Toolkit. Klasa ta posiada metodę getScreenSize(), która to zwraca obiekt typu Dimension zawierający dwie składowe - wysokość i szerokość ekranu. Oto mały fragment kodu, który można użyć:

Toolkit zestaw = Toolkit.getDefaultToolkit();
Dimension wymiary = zestaw.getScreenSize();
int wysokosc = wymiary.height;
int szerokosc = wymiary.width;

Obiekt Dimension to taki odpowiednik struktury w języku C - jego składowe są publicznie dostępne ( tak jak domyślnie w strukturach w C ). Te składowe to height i width, których znaczenia chyba tłumaczyć nie trzeba. Więcej o klasie Toolkit można znaleść w dokumencji na stronie Toolkit

03
lip

Wylistowanie dostępnych czcionek

Prosta klasa, która wypisze nam wszystkie dostępne czcionki, jedna pod drugą:

import java.awt.*;
public class font {
public static void main(String[] args) {
String[] font_names = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
for ( int i = 0; i < font_names.length; i++ )
System.out.println( font_names[i] );
}
}

Metoda getAvailableFontFamilyNames() zwraca tablicę stringów z nazwami czcionek.

01
lip

Let’s Swing

Lipiec zacząłem od zabawy z Javą. Stworzyłem swoją pierwszą okienkową aplikację w tym języku - banalnie prosta, ale od czegoś trzeba zacząć :) ( i nie jest to hello world )

import javax.swing.*;
public class ramka {
/**
* @param args
*/
public static void main(String[] args) {
JFrame window = new JFrame();
window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
window.setSize( 300, 500 );
window.setVisible( true );
window.show();
}
}

Prawda, że piękny efekt? :)

20
wrz

C++ vs Java

Wiele osób próbuje mnie przekonać, że programowanie w Javie jest lepsze i łatwiejsze. Tak mnie naszło napisać przykadowe funkcje w obu tych językach. Obie sprawdzają czy podany wyraz jest palindromem. Oto kod w C++:

bool isPalindrome( string text )
{
  string rev;
  string::reverse_iterator strIter;
  for ( strIter = text.rbegin(); strIter != text.rend(); strIter++ )
       rev.push_back( *strIter );

return rev == text;
}

oraz kod w Javie:

public boolean isPalindrom( String text ){
     StringBuilder str = new StringBuilder( text );
     StringBuilder rev = new StringBuilder( text );
     rev.reverse();
     // cast StringBuilder objects to String and then compare
     if ( (str.toString()).equals( rev.toString() ) ) return true;
     return false;
}

Jakoś dla mnie kod w C++ jest dużo przyjemniejszy do czytania i do pisania ( przynajmniej w tym wypadku ). W Javie musiałem jakieś rzutowania wykonywać z typu StringBuilder na String. Nieco niezrozumiałe dla mnie. Wogóle nie rozumiem dlaczego klasa String jest w Javie stała.

Co do szybkości to testów nie robiłem ( i nie mam zamiaru ). Ciągle się słyszy, że Java jest wolna, chociaż z tego co wiem to nie jest już aż tak wolna jak wszyscy pieją. Przy tak małym programiku jest to zdecydowanie do pominięcia. Chciałem porownać tylko wygodę pisania :)

Pewnie by mi ktoś zarzucił, że jeden język jest lepszy do pewnych rzeczy, drugi do innych. Ale póki co wolę jednak C++ :)