1. Итак напишим:
код Phonebook.java:
import java.awt.event.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*; public class Phonebook extends JFrame { public Phonebook() { } static { System.loadLibrary("phonebook"); } private native void addPhone(String name, String phonenumber, String fax, String email); private native int getRecordsCount(); private native String getPhone(int id); public static void main(String[] args) { new Phonebook(); } }
2. Дадим команду javac -h . PhoneBook.java
3. Создадим пустой проект в Dev-C++
4. Вставим Phonebook.h:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Phonebook */ #ifndef _Included_Phonebook #define _Included_Phonebook #ifdef __cplusplus extern "C" { #endif #undef Phonebook_FOCUS_TRAVERSABLE_UNKNOWN #define Phonebook_FOCUS_TRAVERSABLE_UNKNOWN 0L #undef Phonebook_FOCUS_TRAVERSABLE_DEFAULT #define Phonebook_FOCUS_TRAVERSABLE_DEFAULT 1L #undef Phonebook_FOCUS_TRAVERSABLE_SET #define Phonebook_FOCUS_TRAVERSABLE_SET 2L #undef Phonebook_TOP_ALIGNMENT #define Phonebook_TOP_ALIGNMENT 0.0f #undef Phonebook_CENTER_ALIGNMENT #define Phonebook_CENTER_ALIGNMENT 0.5f #undef Phonebook_BOTTOM_ALIGNMENT #define Phonebook_BOTTOM_ALIGNMENT 1.0f #undef Phonebook_LEFT_ALIGNMENT #define Phonebook_LEFT_ALIGNMENT 0.0f #undef Phonebook_RIGHT_ALIGNMENT #define Phonebook_RIGHT_ALIGNMENT 1.0f #undef Phonebook_serialVersionUID #define Phonebook_serialVersionUID -7644114512714619750i64 #undef Phonebook_serialVersionUID #define Phonebook_serialVersionUID 4613797578919906343i64 #undef Phonebook_INCLUDE_SELF #define Phonebook_INCLUDE_SELF 1L #undef Phonebook_SEARCH_HEAVYWEIGHTS #define Phonebook_SEARCH_HEAVYWEIGHTS 1L #undef Phonebook_OPENED #define Phonebook_OPENED 1L #undef Phonebook_serialVersionUID #define Phonebook_serialVersionUID 4497834738069338734i64 #undef Phonebook_DEFAULT_CURSOR #define Phonebook_DEFAULT_CURSOR 0L #undef Phonebook_CROSSHAIR_CURSOR #define Phonebook_CROSSHAIR_CURSOR 1L #undef Phonebook_TEXT_CURSOR #define Phonebook_TEXT_CURSOR 2L #undef Phonebook_WAIT_CURSOR #define Phonebook_WAIT_CURSOR 3L #undef Phonebook_SW_RESIZE_CURSOR #define Phonebook_SW_RESIZE_CURSOR 4L #undef Phonebook_SE_RESIZE_CURSOR #define Phonebook_SE_RESIZE_CURSOR 5L #undef Phonebook_NW_RESIZE_CURSOR #define Phonebook_NW_RESIZE_CURSOR 6L #undef Phonebook_NE_RESIZE_CURSOR #define Phonebook_NE_RESIZE_CURSOR 7L #undef Phonebook_N_RESIZE_CURSOR #define Phonebook_N_RESIZE_CURSOR 8L #undef Phonebook_S_RESIZE_CURSOR #define Phonebook_S_RESIZE_CURSOR 9L #undef Phonebook_W_RESIZE_CURSOR #define Phonebook_W_RESIZE_CURSOR 10L #undef Phonebook_E_RESIZE_CURSOR #define Phonebook_E_RESIZE_CURSOR 11L #undef Phonebook_HAND_CURSOR #define Phonebook_HAND_CURSOR 12L #undef Phonebook_MOVE_CURSOR #define Phonebook_MOVE_CURSOR 13L #undef Phonebook_NORMAL #define Phonebook_NORMAL 0L #undef Phonebook_ICONIFIED #define Phonebook_ICONIFIED 1L #undef Phonebook_MAXIMIZED_HORIZ #define Phonebook_MAXIMIZED_HORIZ 2L #undef Phonebook_MAXIMIZED_VERT #define Phonebook_MAXIMIZED_VERT 4L #undef Phonebook_MAXIMIZED_BOTH #define Phonebook_MAXIMIZED_BOTH 6L #undef Phonebook_serialVersionUID #define Phonebook_serialVersionUID 2673458971256075116i64 /* * Class: Phonebook * Method: addPhone * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_Phonebook_addPhone (JNIEnv *, jobject, jstring, jstring, jstring, jstring); /* * Class: Phonebook * Method: getRecordsCount * Signature: ()I */ JNIEXPORT jint JNICALL Java_Phonebook_getRecordsCount (JNIEnv *, jobject); /* * Class: Phonebook * Method: getPhone * Signature: (I)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Phonebook_getPhone (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif
5. Вставим в Phonebook.c:
#define FILENAME "phonebook.bin" // Имя файла, константа #define MAX_SIZE_BUF sizeof(RECORD) // Максимальный размера буфера, константа #include <jni.h> #include <stdio.h> #include "Phonebook.h" // Запись телефонной книжки typedef struct { char name[512]; // Имя фамилия char phonenumber[30]; // Номер телефона char fax[30]; // Номер факса char email[40]; // Эл.почта } RECORD; // Проверка существует ли файл int file_exist() { FILE *f; f = fopen(FILENAME, "r+b"); if(f == NULL) return -1; else { fclose(f); return 0; } } //Добавляет запись JNIEXPORT void JNICALL Java_Phonebook_addPhone(JNIEnv *env, jobject obj, jstring name, jstring phonenumber, jstring fax, jstring email) { FILE *f; RECORD rec; if(strlen((*env)->GetStringUTFChars(env, name, NULL)) > 512) return; if(strlen((*env)->GetStringUTFChars(env, phonenumber, NULL)) > 30) return; if(strlen((*env)->GetStringUTFChars(env, fax, NULL)) > 30) return; if(strlen((*env)->GetStringUTFChars(env, email, NULL)) > 40) return; f = fopen(FILENAME, "a+b"); strcpy(rec.name, (*env)->GetStringUTFChars(env, name, NULL)); strcpy(rec.phonenumber, (*env)->GetStringUTFChars(env, phonenumber, NULL)); strcpy(rec.fax, (*env)->GetStringUTFChars(env, fax, NULL)); strcpy(rec.email, (*env)->GetStringUTFChars(env, email, NULL)); fwrite(&rec, sizeof(RECORD), 1, f); fclose(f); } //Читает запись JNIEXPORT jstring JNICALL Java_Phonebook_getPhone(JNIEnv *env, jobject obj, jint recordid) { FILE *f; RECORD rec; int index=0; char buf[4096]; f = fopen(FILENAME, "r+b"); fseek(f, sizeof(RECORD)*recordid, SEEK_CUR); fread(&rec, sizeof(RECORD), 1, f); sprintf(buf, "%s~%s~%s~%s", rec.name, rec.phonenumber, rec.fax, rec.email); return (*env)->NewStringUTF(env, buf); fclose(f); } // Возвращает количество записей в телефонной книжки JNIEXPORT jint JNICALL Java_Phonebook_getRecordsCount(JNIEnv *env, jobject obj) { FILE *f; RECORD rec; int max; char buf[MAX_SIZE_BUF+1]; // Проверяем есть ли файл, если нет, то возвращаем пустое количество записи и создаём файл if(file_exist() == -1) { f = fopen(FILENAME, "w+b"); fclose(f); return 0; } f = fopen(FILENAME, "r+b"); fseek(f, 0L, SEEK_END); max = ftell(f); fclose(f); return max/sizeof(RECORD); }
6. Выберем что проект Dll.
7. Подредактируем форму "Новая запись", я буду делать это в Borland JBuilder 5.
8. Добавим код в Phonebook.java:
import java.awt.event.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*; public class Phonebook extends JFrame { private JTable tblDemo = null; private DefaultTableModel tblModel = null; // Считывает данные из файла, и добавляет их в сетку private void GetItems() { String[] arrColumns = {"ID", "Имя", "Телефон", "Факс", "Эл.почта"}; String str = ""; String arrdata[] = null; tblModel = new DefaultTableModel(arrColumns, 0); tblDemo = new JTable(tblModel); add(new JScrollPane(tblDemo)); for(int j=0; j<getRecordsCount(); j++) { str = getPhone(j); arrdata = str.split("~"); tblModel.addRow(new Object[]{new Integer(j), arrdata[0], arrdata[1], arrdata[2], arrdata[3]}); } } // Конструктор public Phonebook() { try { setTitle("Записная книжка"); setSize(640, 480); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); GetItems(); JMenuBar bar = new JMenuBar(); JMenu mnuFile = new JMenu("Файл"); JMenuItem popupNewRecord = new JMenuItem("Добавить новую запись"); popupNewRecord.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ JFrame frm = new JFrame(); JLabel lbName = new JLabel("Имя:"); JLabel lbPhone = new JLabel("Телефон:"); JLabel lbFax = new JLabel("Факс:"); JLabel lbEmail = new JLabel("Эл.почта:"); JTextField txtName = new JTextField(); JTextField txtPhone = new JTextField(); JTextField txtFax = new JTextField(); JTextField txtEmail = new JTextField(); JButton btnOK = new JButton("Сохранить"); JButton btnCancel = new JButton("Отменить"); // lbName.setBounds(new Rectangle(15, 10, 45, 20)); lbName.setBounds(new Rectangle(15, 10, 75, 20)); txtName.setBounds(new Rectangle(15, 33, 372, 29)); //txtName.setMargin(new Insets(10, 10, 10, 10)); // lbPhone.setBounds(new Rectangle(15, 82, 45, 20)); lbPhone.setBounds(new Rectangle(15, 82, 75, 20)); txtPhone.setBounds(new Rectangle(15, 101, 171, 29)); // lbFax.setBounds(new Rectangle(15, 143, 29, 20)); lbFax.setBounds(new Rectangle(15, 143, 75, 20)); txtFax.setBounds(new Rectangle(15, 162, 172, 29)); // lbEmail.setBounds(new Rectangle(15, 205, 42, 20)); lbEmail.setBounds(new Rectangle(15, 205, 75, 20)); txtEmail.setBounds(new Rectangle(15, 224, 367, 29)); // btnOK.setBounds(new Rectangle(9, 269, 92, 43)); btnOK.setBounds(new Rectangle(9, 269, 122, 43)); // btnCancel.setBounds(new Rectangle(102, 269, 92, 43)); btnCancel.setBounds(new Rectangle(142, 269, 92, 43)); frm.setTitle("Новая запись"); frm.setSize(440, 450); frm.setLayout(null); frm.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); btnOK.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ Object[] objOptions = { "Ок" }; if(txtName.getDocument().getLength() > 255 || txtPhone.getDocument().getLength() > 30 || txtFax.getDocument().getLength() > 30 || txtEmail.getDocument().getLength() > 40) { JOptionPane.showOptionDialog(null, "Слишком длинный текст!", "Ошибка", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, objOptions, objOptions[0]); return; } /*if(txtPhone.getText().getLength() > 30) if(txtFax.getText().getLength() > 30) if(txtEmail.getText().getLength() > 30)*/ addPhone(txtName.getText(), txtPhone.getText(), txtFax.getText(), txtEmail.getText()); getContentPane().remove(tblDemo); GetItems(); getContentPane().repaint(); frm.dispose(); } }); btnCancel.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e){ frm.dispose(); } }); frm.add(lbName); frm.add(txtName); frm.add(lbPhone); frm.add(txtPhone); frm.add(lbFax); frm.add(txtFax); frm.add(lbEmail); frm.add(txtEmail); frm.add(btnOK); frm.add(btnCancel); frm.setVisible(true); } }); mnuFile.add(popupNewRecord); bar.add(mnuFile); setJMenuBar(bar); setVisible(true); } catch(Exception ex) { } } static { System.loadLibrary("phonebook"); } private native void addPhone(String name, String phonenumber, String fax, String email); // Добавить телефон private native int getRecordsCount(); // Получить количество записей из файла private native String getPhone(int id); // Считать определённу запись из файла public static void main(String[] args) { new Phonebook(); } }
9. Запускаем ещё раз компилятор:
javac -encoding utf8 Phonebook.java
10. Запускаем приложение java Phonebook
Результат:
Добавляем Anton Mustermann:
Если сильно длинный текст, то выдаст предупреждение Слишком длинный текст:
Вуаля, Anton Mustermann сохранился: