Category Archives: Java

PartManager v0.1a

By | 30. November 2018

Ich war vor einiger Zeit auf der Suche nach einem schlanken Programm zur Verwaltung meiner elektronischen Bauteile. Leider waren die meisten Tools überladen und kompliziert in der Bedienung. Also entschloss ich mich, selbst eines zu schreiben. Bisher habe ich es für meine eigenen Zwecke genutzt, möchte es aber zur freien Nutzung zur Verfügung stellen und auch weiterentwickeln.

Im PartManager können Bauteile und ihre Verfügbarkeit im persönlichen “Lager” verwaltet werden. Beim Anlegen eines Datensatzes können Informationen von Conrad, Reichelt, Digikey, Pollin, Voelkner, Mouser, Watterott, Farnell, Amazon und Ebay importiert werden. Weiterhin können virtuelle Lagerkisten angelegt werden und diese mit Bauteilen gefüllt werden.

Der PartManager ist momentan noch im Alpha-Stadium und wird voraussichtlich im Frühling 2019 weiterentwickelt.

Download: PartManager

Kimsufi Crawler

By | 28. Februar 2016

Kimsufi Crawler

Wenn man sich bei Kimsufi einen neuen Server zulegen möchte, ist das meist mit langen Wartezeiten verbunden. Eine hauseigene Benachrichtigung zur Verfügbarkeit wird leider nicht angeboten und die manuelle Abfrage der Seite ist unter Umständen nicht schnell genug, sodass man einen verfügbaren Server nicht bemerkt. Aus diesem Grund habe ich einen kleinen Crawler geschrieben, der in beliebigen Intervallen die Verfügbarkeit des gewünschten Servers überprüft. Ist der Server verfügbar, so öffnet sich ein Popup und der Browser öffnet direkt den Link zum Bestellformular.



package im.jahnke.kimsuficrawler;
 
import java.awt.Desktop;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URL;
import java.util.Scanner;
 
import javax.net.ssl.HttpsURLConnection;
import javax.swing.JOptionPane;
 
/**
 * KimsufiCrawler is a tool for checking the availability of Kimsufi servers 
 * 
 */
 
public class KimsufiCrawler {
     
    public static void main(String[] args) throws Exception {
         
        Scanner sc = new Scanner(System.in);
         
        System.out.println("Kimsufi Server Scanner");
        System.out.println("1 \t KS-1");
        System.out.println("2A \t KS-2A");
        System.out.println("2B \t KS-2B");
        System.out.println("2C \t KS-2C");
        System.out.println("2D \t KS-2D");
        System.out.println("3A \t KS-3A");
        System.out.println("3B \t KS-3B");
        System.out.println("3C \t KS-3C");
        System.out.println("3D \t KS-3D");
        System.out.println("4A \t KS-4A");
        System.out.println("4B \t KS-4B");
        System.out.println("4C \t KS-4C");
        System.out.println("4D \t KS-4D");
        System.out.println("5 \t KS-5");
        System.out.print("Choose Server: ");
        
        String chosenServer = "";
        switch (sc.nextLine()) {
        case "1":
            chosenServer = "160sk1";
            break;
        case "2A":
            chosenServer = "160sk2";
            break;
        case "2B":
            chosenServer = "160sk21";
            break;
        case "2C":
            chosenServer = "160sk22";
            break;
        case "2D":
            chosenServer = "160sk23";
            break;
        case "3A":
            chosenServer = "160sk3";
            break;
        case "3B":
            chosenServer = "160sk31";
            break;
        case "3C":
            chosenServer = "160sk32";
            break;
        case "3D":
            chosenServer = "160sk33";
            break;
        case "4A":
            chosenServer = "160sk4";
            break;
        case "4B":
            chosenServer = "160sk41";
            break;
        case "4C":
            chosenServer = "160sk42";
            break;
        case "4D":
            chosenServer = "160sk43";
            break;
        case "5":
            chosenServer = "160sk5";
            break;
        default:
            chosenServer = "";
            break;
        }
         
        System.out.print("Sleeping time in seconds: ");
        int sleepingTime = sc.nextInt()*1000;
         
        sc.close();
         
        while(true){
            System.out.println("Scanning for available server...");
            String pageContent = getPageContent("https://www.kimsufi.com/en/order/kimsufi.cgi?hard=" + chosenServer + "&dedicatedQuantity=1");
            if(!pageContent.contains("invalide") && !pageContent.contains("rapprovisionnement")){                
                Desktop.getDesktop().browse(new URI("https://www.kimsufi.com/en/order/kimsufi.cgi?hard=" + chosenServer + "&dedicatedQuantity=1"));
                JOptionPane.showMessageDialog(null, "Alarm");
                return;
            } else {
                System.out.println("No free servers found...");
            }
             
            Thread.sleep(sleepingTime);
            System.gc();
        }
    }
     
    private static String getPageContent(String url) throws Exception {
 
        String inputLine;
        StringBuffer response = new StringBuffer();
         
        URL obj = new URL(url);
        HttpsURLConnection conn = (HttpsURLConnection) obj.openConnection();
 
        conn.setRequestMethod("GET");
 
        conn.setUseCaches(false);
 
        conn.setRequestProperty("User-Agent", "Mozilla/2.0");
        conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
         
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
             
 
            while ((inputLine = in.readLine()) != null) {
                response.append(inputLine);
            }
            in.close();
            conn.disconnect();
            conn = null;
        } catch (Exception e) {
            response.append("invalide");
        }
 
        return response.toString();
 
    }
 
}


Das Git-Repository kann hier verfolgt werden: Link

Java-Programme neustarten

By | 2. Januar 2015

Im Internet taucht immer wieder die Frage auf, wie man Java-Programme im .jar-Format neustarten kann. Lösungen sind allerdings rar. Also habe ich mich umgeschaut und mit den vorhandenen Informationen eine lauffähige Version geschrieben.

String javaBin = System.getProperty("java.home") + "/bin/java";
File jarFile;
try{
    jarFile = new File
    (getClass().getProtectionDomain()
    .getCodeSource().getLocation().toURI());
    } catch(Exception e) {
    return;
}
if ( !jarFile.getName().endsWith(".jar") )
return;
 
String toExec[] = new String[] { javaBin, "-jar", jarFile.getPath() };
try{
    @SuppressWarnings("unused")
    Process p = Runtime.getRuntime().exec( toExec );
    } catch(Exception e) {
    e.printStackTrace();
    return;
}
 
System.exit(0);

JEditorPane Syntax Highlighter

By | 16. November 2013

Nachdem ich lange vergeblich auf der Suche nach einem Assembler Syntax Highlighter war, habe ich mich entschieden, einen Java Highlighter für diese Zwecke zu “missbrauchen”.

Zunächst werden der Quellcode für das modifizierte JEditorPane und die Library JSoup benötigt.

Download
syntax.java | 23 kB
Download
jsoup-1.8.3.jar | 284 kB

Die entsprechenden Keywords stehen in der Hashmap des Konstruktors und können beliebig angepasst, vermehrt und gelöscht werden.

assemblerKeywords.put("mov", DEFAULT_KEYWORD);
assemblerKeywords.put("inc", DEFAULT_KEYWORD);
assemblerKeywords.put("lcall", DEFAULT_KEYWORD);

Um dieses modifizierte JEditorPane schließlich auf einen Frame zu packen, kann man sich das Pane mit der Methode getEditPane() holen.

JEditorPane codebox = (JEditorPane) new Syntax().getEditPane();

Das Casten ist notwendig, da die Methode das Pane zunächst nur als JComponent zurück gibt. Es gibt bestimmt bequemere und vor allem sauberere Lösungen, aber einen Syntax Highlighter selbst zu schreiben, überfordert mich als Java-Anfänger dann doch ein wenig ;)

Ternärer Operator in Java

By | 4. November 2013

Eine interessante Möglichkeit, um diese lästigen if-else-Klammern ein bisschen zu reduzieren, ist der ternäre Operator. Die allgemeine Form ist: x = BOOL_TEST ? TRUE_FALL : FALSE_FALL

Beispiel:

max = (a > b) ? a : b;

Die ursprüngliche Form mit if-else:

if (a > b) {
	max = a;
}
else {
	max = b;
}

Java Hangman

By | 31. Oktober 2013

Wenn man einfach mal Lust hat, etwas Kleines zu programmieren, nimmt man gerne einen alten Klassiker. Ich habe mich für Hangman (“Galgenmännchen”) entschieden. Diese Version ist sehr minimalistisch gehalten. Vielleicht füge ich demnächst noch eine GUI hinzu.

Eine Liste mit über 5000 Wörtern, passend für das Spiel:

Download
words.txt | 52 kB

View.java

public class View {

	public View(){
		Core core = new Core();
		core.newRound();	 
	}
	
	public static void main(String args[]) {
		new View();
	}
}

Core.java

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
 
public class Core {
 
	private List<Word> words = new ArrayList<>();
	private Word round;
	 
	public Core() {
		loadWordList();
	}
	 
	public void loadWordList() {
		String line = "";
		try {
			File file = new File(this.getClass().getClassLoader()
			.getResource("words.txt").getFile());
			@SuppressWarnings("resource")
			BufferedReader in = new BufferedReader(new FileReader(file));
			while ((line = in.readLine()) != null) {
				words.add(new Word(line));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	 
	public void newRound() {
		round = words.get(new Random().nextInt(words.size()));
		while (!round.checkIfFinished()) {
			System.out.println(String.valueOf(round.getToSolve()));
			round.guessChar(readChar());
			if (round.getGuessCounter()>8) {
				break;
			}
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		if (round.checkIfFinished()) {
			System.out.println("Gewonnen!");
		} else {
			System.out.println("Verloren!");
			System.out.println("Das gesuchte Wort lautete: " + String.valueOf(round.getWord()));
		}
	}
	 
	public char readChar() {
		BufferedReader read = new BufferedReader(new InputStreamReader(
		System.in));
		String input = new String();
		try {
			input = read.readLine();
		} catch (java.io.IOException e) {
			System.out.println(e);
		}
		char back = input.charAt(0);
		return back;
	}
}

Word.java

public class Word {
 
	private char[] word;
	private int size;
	private int guessCounter = 0;
	 
	private char[] toSolve;
	 
	public Word(String word) {
		this.word = word.toUpperCase().toCharArray();
		size = this.word.length;
		toSolve = new char[size];
		for (int i = 0; i < toSolve.length; i++) {
			toSolve[i] = '_';
		}
	}
	 
	public char[] getWord() {
		return word;
	}
	 
	public int getSize() {
		return size;
	}
	 
	public char[] getToSolve() {
		return toSolve;
	}
	 
	public int getGuessCounter() {
		return guessCounter;
	}
	 
	public boolean guessChar(char c){
		boolean guess = false;
		c = Character.toUpperCase(c);
		for (int i=0; i<word.length; i++) {
			if (c==word[i]) {
				toSolve[i] = c;
				guess = true;
			}
		}
		if (guess) {
			System.out.println("Der Buchstabe " + c + " war dabei!");
		} else {
			guessCounter++;
			System.out.println("Der Buchstabe " + c + " war nicht dabei!");
		}
		return guess;
	}
	 
	public boolean checkIfFinished(){
		boolean finished = true;
		for (int i = 0; i < toSolve.length; i++) {
			if (toSolve[i]== '_') {
				finished = false;
			}
		}
		return finished;
	} 
}

Zahlenrechner

By | 28. Oktober 2013

Der Zahlenrechner ist ein kleines Programm, dass ich nach 3 Monaten Einarbeitung in Java schreiben wollte, es aber nie fertiggestellt habe. Es kann Zahlen zwischen den Systemen 2 bis 32 in jeweils ein anderes umrechnen. Heute habe ich mich endlich an die Fertigstellung gemacht und veröffentliche hier den Quellcode.

zahlenrechner[1]

Model.java

public class Model {
 
	final char[] ziffern = { '0', '1', '2', '3', '4', '5', '6', '7',
	'8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
	'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
	'y', 'z' };
	 
	public int zuDezimal(String eingabe, int system) {
		char[] zahl = eingabe.toLowerCase().toCharArray();
		int ergebnis = 0;
		int counter = 0;
		for (int i = zahl.length - 1; i &gt;= 0; i--) {
			ergebnis += (int) (holeZahlenWert(zahl[i]) * Math.pow(system, counter));
			counter++;
		}
		return ergebnis;
	}
	 
	public int holeZahlenWert(char ziffer) {
		for (int i = 0; i &lt; ziffern.length; i++) {
			if (ziffer==ziffern[i]) {
				return i;
			}		 
		}
		return 0;
	}
	 
	public char gibZahlenZeichen(int zahl) {
		return ziffern[zahl];	 
	}
	 
	public String rechne(int zahl, int zielsystem) {
		String ergebnis = "";
		boolean weiter = true;
		while (weiter) {
			ergebnis = gibZahlenZeichen(zahl%zielsystem) + ergebnis;
			zahl = (int)zahl/zielsystem;
			if(zahl==0) {
				break;
			}
		}
		return ergebnis.toUpperCase();
	} 
}

View.java

import java.awt.Container;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
 
public class View {
 
	JTextField input = new JTextField();
	JTextField output = new JTextField();
	JButton button = new JButton("Umrechnen");
	JComboBox startsystem = new JComboBox();
	JComboBox zielsystem = new JComboBox();
	 
	public View() {
		JFrame frame = new JFrame("Zahlenrechner");
		Container cp = frame.getContentPane();
		cp.setLayout(null);
		cp.setFocusable(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(280, 140);
		input.setBounds(10, 10, 130, 25);
		cp.add(input);
		output.setBounds(10, 40, 130, 25);
		cp.add(output);
		startsystem.setBounds(150, 10, 100, 25);
		cp.add(startsystem);
		zielsystem.setBounds(150, 40, 100, 25);
		cp.add(zielsystem);
		fillLists();
		button.setMargin(new Insets(5, 5, 5, 5));
		button.setBounds(10, 70, 130, 25);
		button.addActionListener(new ActionListener() {
		
			@Override
			public void actionPerformed(ActionEvent arg0) {
				int start = 2+startsystem.getSelectedIndex();
				int ziel = 2+zielsystem.getSelectedIndex();
				String in = input.getText();
				Model m = new Model();
				output.setText(m.rechne(m.zuDezimal(in, start), ziel));
			}
		});
		cp.add(button);
		frame.setVisible(true);
	}
	 
	public void fillLists(){
		String[] namen = {"2 (binär)", "3", "4", "5", "6", "7",
		"8 (oktal)", "9", "10 (dezimal)", "11",
		"12", "13", "14", "15", "16 (hexadezimal)",
		"17", "18", "19", "20", "21", "22", "23",
		"24", "25", "26", "27", "28", "29", "30",
		"31", "32", "33", "34", "35", "36"};
		for (int i = 0; i &lt; namen.length; i++) {
			startsystem.addItem(namen[i]);
			zielsystem.addItem(namen[i]);
		}
	}
	 
	public static void main(String[] args) {
		new View();
	} 
}

LCD-Anzeige

By | 19. Juli 2013

Da ich momentan noch an einem größeren Projekt arbeite und dieses eine LCD-Anzeige benötigt, habe ich mir gedacht, ich veröffentliche den Ausschnitt mal.

lcd[1]

Vielleicht ist ja jemand auf der Suche danach oder will sich nicht extra die Mühe machen, selbst etwas zu basteln. Bitte hinterlasst einen Kommentar, falls ihr das Display in euer Programm mit einbauen wollt. Ich bin gespannt, zu was es eingesetzt wird.

Zuerst der Code und dann die Erklärungen:

Start.java

import javax.swing.JFrame;
 
@SuppressWarnings("serial")
public class Start extends JFrame {
 
	Display anzeige;
	 
	public Start() {
		setSize(320, 110);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		anzeige = new Display();
		 
		//Anfangstext
		String text = "jahnke.im";
		for (int i = 0; i < text.length(); i++) {
			anzeige.setCursorPos(i);
			anzeige.setChar(text.charAt(i));
		}
		
		add(anzeige);
		setTitle("LCD-Display");
		 
		setVisible(true);
	}
	 
	public static void main(String[] args) {	 
		new Start();	 
	} 
}

Display.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
 
import javax.imageio.ImageIO;
import javax.swing.JPanel;
 
@SuppressWarnings("serial")
public class Display extends JPanel {
 
	Pixel[][][] display = new Pixel[32][8][5];
	private int position_x = 10;
	private int position_y = 10;
	private int cursorPos = 0;
	 
	private boolean[][][] charTable = new boolean[256][8][5];
	 
	public Display() {
		init();
		for (int i = 0; i < display.length; i++) {
			for (int j = 0; j < display[0].length; j++) {
				for (int k = 0; k < display[0][0].length; k++) {				 
					display[i][j][k] = new Pixel(false, position_x, position_y);
					position_x += 3;				 
				}
				position_x -= 15;
				position_y += 3;
			}
			position_x += 18;
			position_y -= 24;
			if (i == 15) {
				position_x -= 288;
				position_y += 27;
			}
		}
	}
	 
	public void paintComponent(Graphics g) {
		g.setColor(new Color(120, 166, 72));
		g.fillRect(0, 0, 400, 400);
		 
		for (int i = 0; i < display.length; i++) {
			for (int j = 0; j < display[0].length; j++) {
				for (int k = 0; k < display[0][0].length; k++) {				
					if (display[i][j][k].isActivated()) {
						g.setColor(new Color(29, 70, 51));
					} else {
						g.setColor(new Color(91, 159, 73));
					}
					g.fillRect(display[i][j][k].getX(), display[i][j][k].getY(), 2, 2);
				}
			}
		}
		this.repaint();	 
	}
	 
	public void init() {	 
		BufferedImage image;
		File file = new File(this.getClass().getClassLoader().getResource("pixeldata.bmp").getPath());
		try {
			image = ImageIO.read(file);
			for (int i = 0; i < 256; i++) {
				for (int y = 0; y < 8; y++) {
					for (int x = 0; x < 5; x++) {
						if (image.getRGB(x + 5 * i, y) < -1) {
							charTable[i][y][x] = true;
						} else {
							charTable[i][y][x] = false;
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}	 
	}
	 
	public void setCursorPos(int pos) {
		cursorPos = pos;
	}
	 
	public void setChar(int chr) {
		int c = chr;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 5; j++) {
				display[cursorPos][i][j].setActivated(charTable[c][i][j]);
			}
		}
	}
	 
	public void setChar(char chr) {
		int c = (int) chr;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 5; j++) {
				display[cursorPos][i][j].setActivated(charTable[c][i][j]);
			}
		}
	}
 
}

Pixel.java

public class Pixel {
 
	private boolean activated;
	private int x;
	private int y;
	 
	public Pixel(boolean activated, int x, int y) {
		this.activated = activated;
		this.x = x;
		this.y = y;
	}
	 
	public boolean isActivated() {
		return activated;
	}
	 
	public void setActivated(boolean activated) {
		this.activated = activated;
	}
	 
	public int getX() {
		return x;
	}
	 
	public void setX(int x) {
		this.x = x;
	}
	 
	public int getY() {
		return y;
	}
	 
	public void setY(int y) {
		this.y = y;
	}
}

Es wurde der Zeichensatz des Displays verwendet: (Leichte Abweichung zum originalen ASCII-Code)

zeichensatz[1]

Die verschiedenen Zeichen werden mithilfe der angehängten Bitmap, die beim Programmstart ausgelesen wird, erzeugt.

Link zur Bitmap

Momentan habe ich noch keine Möglichkeit mit eingebaut, den Text zur Laufzeit zu ändern. Aber ich denke, ein Textfeld mit einzubauen sollte für niemanden ein Problem darstellen.

Der Text wird in der Start.java definiert: z.B.:

anzeige.setCursorPos(0);
anzeige.setChar('A');
//oder:
anzeige.setCursorPos(0);
anzeige.setChar(65);

Eine einfache Methode in Display.java genügt, um den Text zur Laufzeit bearbeiten zu können. Diese sollte selbstklärend sein. Andernfalls genügt eine kurze Mail über das Kontaktformular an mich.