|
Java форум JavaTalks форум программистов
|
|
|
|
| Предыдущая тема :: Следующая тема |
| Автор |
Сообщение |
127.0.0.1 : 240 Новичок
|
Фев 10, 2008 18:06 |
|
|
Здравствуйте.
Видел здесь одну тему "Паралелльное обновление данных с GUI", но она осталась незавершенной вроде - у меня аналогичный трабл:
Есть класс, запускаемый в потоке-диспетчере событий, он отвечает за GUI. На этой GUI-форме имется экземпляр JTable и JButton, по нажатию на jButton1 порождается
Новый класс-поток, отвечающий за логику программы. Этот класс конструируется с параметром jTable1. Необходимо: синхронно по мере выполнения логики изменять jTable1, но этого не происходит - табличка изменяется только по завершению работы потока.
Если у кого имеются какие соображения, поделитесь пож.
PS:приоритетность не помогла, туториал смотрел. |
|
|
|
 |
Vlad : 1669 JavaTalks Team Member Откуда: ODS-KRK-LON-HFE
|
Фев 11, 2008 14:02 |
|
|
|
|
|
|
 |
127.0.0.1 : 240 Новичок
|
Фев 11, 2008 21:13 |
|
|
| спс, но на первый взгляд приводимые примеры от моего кода практически не отличаются. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 12, 2008 19:20 |
|
|
| Дело не в потоках. Ты модель таблицы используешь? |
|
|
|
 |
127.0.0.1 : 240 Новичок
|
Фев 13, 2008 13:00 |
|
|
Использую конечно, наследованную от Defaultовской. И fireTableDataChanged вроде есть.  |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 13, 2008 15:26 |
|
|
| Тогда код приводи, ясновидящих тут нет... |
|
|
|
 |
127.0.0.1 : 240 Новичок
|
Фев 14, 2008 0:29 |
|
|
код, дак код, не хотел кого-то им нагружать - думал это есть распространенная проблема и идеологически решение стандартное.
Задача:
Требуется реализовать программу подсчета вхождений символов установленного алфавита в определенном текстовом файле.
Алфавит задается в текстовом файле, в формате символ\n[символ\n]. Под символом понимается буква латинского алфавита или цифра.
Программа должна выполнять проверку уникальности символа в алфавите, т.е. если в файле алфавита найден повторяющийся символ, программа должна вывести сообщение с символом и номерами строк, где он повторяется. Если найдены дубликаты символов процесс подсчета вхождений не может быть начат.
Проверку на дозволенные символы в алфавите проводить не требуется. Предполагается, что там будут только символы латинского алфавита и цифры.
Пример файла алфавита:
a
b
c
...
y
z
Требования к интерфейсу приложения:
Графический интерфейс пользователя должен быть реализован при помощи набора графических компонент Swing.
Программа должна позволять выбирать пути к файлу алфавита и текстовому файлу для поиска. По умолчанию должны быть выбраны файлы alphabet.txt и heap.txt в каталоге запуска программы.
Прогресс процесса выполнения подсчета должен быть отражен при помощи компоненты progress bar. 0% соответствует моменту начала поиска, 100% соответствует моменту завершения поиска.
Результат поиска должен быть отражен в таблице с двумя колонками: символ и число вхождений. Должна быть возможность отсортировать таблицу по обеим колонкам при нажатии на заголовки колонок.
Необходимо предусмотреть возможность динамического вывода вхождений символов в процессе подсчета. Т.е. необходим checkbox, при включении которого таблица вхождений начинает изменяться в процессе подсчета, а при выключении таблица заполняется после завершения подсчета.
Реализована след структура:
1.ГУИ-взимодейстие с пользователем:
| Код: |
package dialogpackage;
/*
* It's graphical user interface class
*
*/
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.filechooser.*;
/**
*
* @author Admin
*/
public class DialogFrame extends javax.swing.JFrame {
private FileToParse fileToParse;
private SelectedAlphabet alphabet;
private Thread thread = null;
boolean dynOutline = false;
/** Creates new form DialogFrame */
public DialogFrame() throws IOException {
fileToParse = new FileToParse("heap.txt");
alphabet = new SelectedAlphabet("alphabet.txt");
initComponents();
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
jProgressBar1 = new javax.swing.JProgressBar();
jButton1 = new javax.swing.JButton();
jCheckBox1 = new javax.swing.JCheckBox();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenuItem1 = new javax.swing.JMenuItem();
jMenuItem2 = new javax.swing.JMenuItem();
jMenuItem3 = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("I would like to work for PL");
setResizable(false);
jTable1.setAutoCreateRowSorter(true);
jTable1.setModel(new AlphabetModel());
jScrollPane1.setViewportView(jTable1);
jButton1.setText("Get entries to selected file");
jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jButton1MouseReleased(evt);
}
});
jCheckBox1.setText("Dynamic output");
jCheckBox1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jCheckBox1ActionPerformed(evt);
}
});
jMenu1.setText("File");
jMenuItem1.setText("Open");
jMenuItem1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jMenuItem1MouseReleased(evt);
}
});
jMenu1.add(jMenuItem1);
jMenuItem2.setText("Alphabet");
jMenuItem2.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jMenuItem2MouseReleased1(evt);
}
});
jMenu1.add(jMenuItem2);
jMenuItem3.setText("Exit");
jMenuItem3.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseReleased(java.awt.event.MouseEvent evt) {
jMenuItem3MouseReleased(evt);
}
});
jMenu1.add(jMenuItem3);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 191, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(jCheckBox1)
.addContainerGap(80, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 203, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton1)
.addComponent(jCheckBox1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
pack();
}// </editor-fold>
private void jMenuItem1MouseReleased(java.awt.event.MouseEvent evt) {
fileToParse = new FileToParse (evt);
}
private void jMenuItem2MouseReleased1(java.awt.event.MouseEvent evt) {
try {
alphabet = new SelectedAlphabet(evt);
} catch (IOException ex) {
Logger.getLogger(DialogFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void jCheckBox1ActionPerformed(java.awt.event.ActionEvent evt) {
dynOutline = true;
}
private void jMenuItem3MouseReleased(java.awt.event.MouseEvent evt) {
this.setVisible(false);
this.dispose();
}
private void jButton1MouseReleased(java.awt.event.MouseEvent evt) {
// try {
jButton1.setEnabled(false);
jMenu1.setEnabled(false);
jProgressBar1.setValue(0);
thread = new Thread() {
@Override public void run(){
try {
AlphabetModel aModel = (AlphabetModel) (jTable1.getModel());
alphabet.loadAlphabet();
alphabet.initTableByAlphabet((AlphabetModel)jTable1.getModel());
//-------------------------------------------------------------
SwingUtilities.invokeLater(new TextParser(jTable1, alphabet,
fileToParse, jProgressBar1, dynOutline, (AlphabetModel)jTable1.getModel()));
} catch (IOException ex) {
Logger.getLogger(DialogFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
thread.start();
jMenu1.setEnabled(true);
jButton1.setEnabled(true);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new DialogFrame().setVisible(true);
} catch (IOException ex) {
Logger.getLogger(DialogFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JCheckBox jCheckBox1;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
private javax.swing.JMenuItem jMenuItem2;
private javax.swing.JMenuItem jMenuItem3;
private javax.swing.JProgressBar jProgressBar1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration
}
|
2. Логика программы в отдельном потоке
| Код: |
package dialogpackage;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;
import javax.swing.JTable;
public class TextParser implements Runnable{
private JTable Table;
private AlphabetModel localModel;
private SelectedAlphabet selectedAlphabet;
private FileToParse fileToParse;
private JProgressBar ProgressBar;
private boolean dOutput;
private Map entries = new HashMap();
TextParser(JTable jTable, SelectedAlphabet jselectedAlphabet,
FileToParse jfileToParse, JProgressBar jProgressBar,
boolean jdynOutline, AlphabetModel locModel) throws IOException {
Table = jTable;
selectedAlphabet = jselectedAlphabet;
fileToParse = jfileToParse;
ProgressBar = jProgressBar;
dOutput = jdynOutline;
localModel = locModel;
}
private void loadText() throws IOException
{
if (entries!=null)
entries.clear();
FileInputStream in = null;
int count = 0;
try {
in = new FileInputStream(this.fileToParse.getFilePath());
int k;
while ((k = in.read()) != -1)
{
count++;
char key =(char)k;
if((selectedAlphabet.getAlphabetVector()).contains(key))
{
if(!entries.containsKey(key)){
//System.err.println(key+" ");
entries.put(key, 1);
}
else{
Integer value = (Integer) entries.get(key);
int entry = value.intValue();
entries.put(key,(int) entry+1);
System.err.println(entries.get(key));
}
// if(dOutput)
//{
localModel.setValueAt(entries.get(key),
(selectedAlphabet.getAlphabetVector()).indexOf(key),1);
localModel.fireTableDataChanged();
//}
this.ProgressBar.setValue(count*100/(int)fileToParse.getFileSize());
}
}
UpdateTable();
}
catch (IOException ioex)
{
JOptionPane.showMessageDialog(null,"Unable to read file", "ERROR!",JOptionPane.ERROR_MESSAGE);
}
finally
{
if (in != null)
{
in.close();
return;
}
}
return;
}
private void UpdateTable()//our table finaly results
{
Iterator it = selectedAlphabet.getAlphabetVector().iterator();
while ( it.hasNext())
{
Object oIt = it.next();
localModel.setValueAt(entries.get(oIt),
(selectedAlphabet.getAlphabetVector()).indexOf(oIt),1);
}
localModel.fireTableDataChanged();
}
public void run(){
try {
loadText();
} catch (IOException ex) {
Logger.getLogger(TextParser.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
|
3. абстракция: модель таблицы и диалог выбора файла+инициализация соотв. переменной.
| Код: |
package dialogpackage;
import java.io.File;
import javax.swing.filechooser.*;
import javax.swing.JFileChooser;
/*
* Abstract file class
*/
public class SelectedFile {
protected File sFile;
protected String pathToFile;
protected long fileSize;
protected JFileChooser fChoosen = new JFileChooser();;
int returnVal;
private class TXTFilter extends FileFilter {
//Accept all directories and *.txt.
public boolean accept(File sf) {
if (sf.isDirectory()) {
return true;
}
Utils ut = new Utils();
String extension = ut.getExtension(sf);
if (extension != null) {
if (extension.equals(ut.txt) ) {
return true;
} else {
return false;
}
}
return false;
}
//The description of this filter
public String getDescription() {
return "*.txt";
}
}
protected void initSelectedFile() {
fChoosen.addChoosableFileFilter(new TXTFilter());
returnVal = fChoosen.showOpenDialog(fChoosen);
if ( returnVal == JFileChooser.APPROVE_OPTION )
{
/*
get file information
*/
sFile = fChoosen.getSelectedFile();
pathToFile = sFile.getAbsolutePath();
this.setFileSize(sFile.length());
}
}
public void setFilePath(String path){
pathToFile = path;
}
public void setFileSize(long size){
fileSize = size;
}
public long getFileSize(){
return this.fileSize;
}
public String getFilePath(){
return this.pathToFile;
}
}
Модель таблицы:
package dialogpackage;
import javax.swing.table.DefaultTableModel;
/**
*
* @author Admin
*/
public class AlphabetModel extends DefaultTableModel{
private int alphabetSize = 0;
private Object [][] alphaTable = new Object[alphabetSize][2];
private String [] colNames = {"letters", "entries"};
AlphabetModel(){
this.setDataVector(alphaTable, colNames);
}
public int getAlphabetSize(){
return this.alphabetSize;
}
public void setAlphabetSize(int size){
this.alphabetSize = size;
}
public void addRow(){
Object[] data = {"",""};
this.addRow(data);
}
public void reset()
{
Object[][]data = null;
this.setDataVector(data, colNames);
}
}
|
4. Уровень работы с ФС: инициализация алфавита + собственно файл:
| Код: |
Таблица
package dialogpackage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Vector;
import javax.swing.JOptionPane;
public class SelectedAlphabet extends SelectedFile{
AlphabetModel localAlphabetModel;
private int alphabetSize;
private Vector isInAlphabet = new Vector();
public SelectedAlphabet(java.awt.event.MouseEvent evt) throws IOException{
this.initSelectedFile();
this.loadAlphabet();
}
public SelectedAlphabet(String path) throws IOException{
this.sFile = new File(path);
this.fChoosen.setSelectedFile(sFile);
this.setFilePath(path);
this.setFileSize(this.sFile.length());
this.loadAlphabet();
}
public boolean loadAlphabet() throws IOException //loading selected alphabet
{
if(isInAlphabet!=null){
isInAlphabet.clear();
}
FileInputStream fin = null;
try {
fin = new FileInputStream(this.getFilePath());
int c;
int line = 0;
while ((c =fin.read()) != -1)
{
if((c != 13)&& (c !=10))
{
if(!isInAlphabet.contains((char)c)){
isInAlphabet.add((char)c);
line++;
}
else{
JOptionPane.showMessageDialog(null,
"Incorrect alphabet: \""+(char)c+
"\"\nrepeated on line "+line+"\nUnable to parse", "ERROR!",
JOptionPane.ERROR_MESSAGE);
return false;
}
}
}
this.setFileSize(line);
alphabetSize = line;
}
catch (IOException ioex)
{
JOptionPane.showMessageDialog(null, "Caught IOException: "
+ ioex.getMessage(), "ERROR!",
JOptionPane.ERROR_MESSAGE);
}
finally {
if (fin != null)
{
fin.close();
return true;
}
}
return true;
}
public void initTableByAlphabet(AlphabetModel localAlphabetModel){
localAlphabetModel.reset();
int i = 0;
while(i<isInAlphabet.size())
{
localAlphabetModel.addRow();
localAlphabetModel.setValueAt(isInAlphabet.get(i), i,0);
localAlphabetModel.fireTableDataChanged();
i++;
}
}
public Vector getAlphabetVector()
{
return isInAlphabet;
}
public int getAlphabetSize()
{
return alphabetSize;
}
}
Файл:
package dialogpackage;
import java.io.File;
public class FileToParse extends SelectedFile{
FileToParse(String string) {
this.sFile = new File(string);
this.fChoosen.setSelectedFile(sFile);
this.setFilePath(string);
this.setFileSize(this.sFile.length());
}
public FileToParse(java.awt.event.MouseEvent evt){
this.initSelectedFile();
}
}
|
4 замечания:
1. Файлы txt не выкладываю, если будет необходимо, вышлю.
2. Вместо массивов используются контейнеры - одно из доп. условий- что усложняет внешний вид. [offtop] идиотский по сравнению с С++ подход в работе с примитивами [/offtop]
3. На маленьких фалах вроде работает, на больших - висит. динамический вывод поставлен по умолчанию, - условие снимается при раскомментировании строк
| Код: |
// if(dOutput)
//{...
//}
|
4. Переделал изначальный класс-поток ( от Thread) в интерфейс от Runnable.
P.S> Код прошу строго не судить - то, что есть мне больших сил стоило написать, т.к. с Явой имею дело недавно. (это значит не надо писать "бугога, афтар ты мудаг, выпей йаду") |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 14, 2008 12:26 |
|
|
Это называется "не локализованная ошибка". Надо теперь убирать строчки по одной, пока ошибка не исчезнет)
Я щас этим тоже займусь, самому интересно. А ты в следующий раз попытайся сократить выкладываемый код. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 14, 2008 13:05 |
|
|
Комментарии не по теме:
1) private class dialogpackage.SelectedFile.TXTFilter не использует поля родительского класса, поэтому его лучше объявить как static
2) Зачем второму конструктору dialogpackage.FileToParse параметр типа java.awt.event.MouseEvent?
3) Тоже самой про первый конструктор класса dialogpackage.SelectedAlphabet
4) Вместо Vector лучше бы использовать HashSet для хранения алфавита. Или LinkedHashSet если важен порядок букв. Впрочем, символы лучше всего хранить в строке...
5) Если dialogpackage.SelectedFile - абстрактный файл, то и описывать его нужно как abstract class
6) Где используются dialogpackage.AlphabetModel.alphabetSize и dialogpackage.AlphabetModel.alphaTable? |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 14, 2008 13:22 |
|
|
Нашел ошибку!
| Код: |
SwingUtilities.invokeLater(new TextParser(jTable1, alphabet,
fileToParse, jProgressBar1, dynOutline, (AlphabetModel)jTable1.getModel())); |
Как ты думаешь, что делает эта строчка?)
Она запускает твой TextParser в гуишном потоке, замораживая интерфейс.
Правильно в твоем случае делать так:
| Код: |
new Thread(new TextParser(jTable1, alphabet,
fileToParse, jProgressBar1, dynOutline, (AlphabetModel)jTable1.getModel())).start(); |
|
|
|
|
 |
127.0.0.1 : 240 Новичок
|
Фев 15, 2008 2:05 |
|
|
Так, Павел, давай по порядку
0) Мои уважение и благодарность не знают границ, т.к. я убил на решение этой проблемы около недели. Я твой должник, искреннее "Спасибо".
1) dialogpackage.SelectedFile.TXTFilter - честно говоря, даже не задумывался.
2)и3) Есть небольшое ухищрение. Сложно объяснить, но все же: если без java.awt.event.MouseEvent, то получится конструктор без параметров и диалоговые окна выскакивают еще до появления формы. почему? пустой конструктор вызывается при инициализации DialogFrame для внутренних объектов... если не понял - можно подробнее.
4) Vector - первое, что мне попалось под руку, когда дошел до запрета на массивы. Почитав туториал, не нашел принципиальных преимуществ других контейнеров в данном контексте.
5) dialogpackage.SelectedFile - абстрактный файл только по логике, т.е. методы для "дочек" не переопределяются, только добавляютя специфичные новые, а если его сделать abstract, то описания методов придется писать в каждой из дочек, т.к. вроде абстрактный класс их (описания) содержать не должен, или должен содержать хотя бы 1 абстрактный, но такового не понадобилось.
6)dialogpackage.AlphabetModel.alphabetSize и dialogpackage.AlphabetModel.alphaTable - последнюю удалил за ненадобностью), а первую сделал на всякий - это же абстракция)
7)SwingUtilities.invokeLater - кучу всего перерыл по этой теме и насколько понял, этот invokeLater как раз и предназначен для того, чтоб интерфейс не тупил, т.е. он делаетЭтоБэкграунд, как в туториале. Не понимаю, почему я здесь не прав. - сделано, опираясь на http://forum.vingrad.ru/s/c8739ea512ff915c3a3d635e90d58107/act-ST/f-107/t-50027.html [offtop]идиотский подход по сравнению с С++ в работе с GUI/потоками[/offtop]
На закуску это все должно использовать generics, и каким местом тут могут быть шаблоны?... Эхо "сей"?
еще раз большое спасибо, очень выручил, с ув. Б. |
|
|
|
 |
Jean : 1989 JavaTalks Team Member Откуда: Санкт-Петербург
|
Фев 15, 2008 9:02 |
|
|
| 127.0.0.1 писал(а): |
| 7)SwingUtilities.invokeLater - кучу всего перерыл по этой теме и насколько понял, этот invokeLater как раз и предназначен для того, чтоб интерфейс не тупил |
Да, эта пара методов (invokeLater, invokeAndWait) как раз и предназначена для того, чтобы интерфейс не тупил. Смысл их в том, что эти два метода запускают обозначенные в них действия в UI-Thread'е. Это такой особый поток, который предназначен для обновления и отрисовки окошек приложения.
Именно поэтому у Вас все и тормозит. Если Вы делаете продолжительные вычисления в UI-Thread'е, то заниматься рисованием диаложек ему просто некогда.
Предполагается, что все вычисления происходят где угодно (в других потоках), а в случае, если нужно обновить UI, используются эти методы. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 15, 2008 12:56 |
|
|
| 127.0.0.1 писал(а): |
2)и3) Есть небольшое ухищрение. Сложно объяснить, но все же: если без java.awt.event.MouseEvent, то получится конструктор без параметров и диалоговые окна выскакивают еще до появления формы. почему? пустой конструктор вызывается при инициализации DialogFrame для внутренних объектов... если не понял - можно подробнее. |
Убрал этот параметр, все работает
| 127.0.0.1 писал(а): |
4) Vector - первое, что мне попалось под руку, когда дошел до запрета на массивы. Почитав туториал, не нашел принципиальных преимуществ других контейнеров в данном контексте.
|
Принципиальное преимущество есть у ArrayList - работает быстрее. И еще быстрее работают строки, но если их строить не операцией +=
Еще быстрее будет работать (Linked)HashSet или (Linked)HashMap, но это потребует дальнейшей абстракции в модели (сейчас она в проекте только "для галочки", и это видно)
| 127.0.0.1 писал(а): |
5) dialogpackage.SelectedFile - абстрактный файл только по логике, т.е. методы для "дочек" не переопределяются, только добавляютя специфичные новые, а если его сделать abstract, то описания методов придется писать в каждой из дочек, т.к. вроде абстрактный класс их (описания) содержать не должен, или должен содержать хотя бы 1 абстрактный, но такового не понадобилось. |
Нет, если просто дописать abstract, работоспособность программы не нарушится, впрочем, это не принципиально.
| 127.0.0.1 писал(а): |
6)dialogpackage.AlphabetModel.alphabetSize и dialogpackage.AlphabetModel.alphaTable - последнюю удалил за ненадобностью), а первую сделал на всякий - это же абстракция)
На закуску это все должно использовать generics, и каким местом тут могут быть шаблоны?... Эхо "сей"? |
Абстракции тут нет. Есть просто небольшой класс-посредник. Вызывающая программа все равно продолжает работать с номерами строк и пр.
Пример абстракции - класс, скажем, PairsTableModel<K,V> (используется как PairsTableModel<Character,Integer>), который работает как HashMap<K,V>, но при этом запоминает порядок ключей и генерирует события для обновления таблицы.
Одновременно это было бы использование шаблонов. |
|
|
|
 |
Jean : 1989 JavaTalks Team Member Откуда: Санкт-Петербург
|
Фев 15, 2008 22:40 |
|
|
[quote="Майоров Павел"]
| 127.0.0.1 писал(а): |
| 127.0.0.1 писал(а): |
4) Vector - первое, что мне попалось под руку, когда дошел до запрета на массивы. Почитав туториал, не нашел принципиальных преимуществ других контейнеров в данном контексте.
|
Принципиальное преимущество есть у ArrayList - работает быстрее. И еще быстрее работают строки, но если их строить не операцией +=
Еще быстрее будет работать (Linked)HashSet или (Linked)HashMap, но это потребует дальнейшей абстракции в модели (сейчас она в проекте только "для галочки", и это видно) |
Принципиальное отличие Vector'а от ArrayList'а в том, что доступ к элементам вектора является потокозащищенным. Как раз поэтому вектор будет несколько медленнее, потому что такой доступ требует дополнительных операций.
Единственное, что есть особенность при работе с итератором. Об этом можно почитать в javadoc'е. |
|
|
|
 |
Майоров Павел : 1460 Java Developer
|
Фев 16, 2008 20:10 |
|
|
| Данный случай (список сначала заполняется, а потом используется) - не из нет, когда встроенные механизмы синхронизации вектора пригодятся. |
|
|
|
 |
|
|
Страница 1 из 2 На страницу 1, 2 След. |
Список форумов
-> Нити и процессы |
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах
|
|