Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Заполнить textarea из другого класса / 15 сообщений из 15, страница 1 из 1
29.04.2018, 17:26
    #39638340
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Здравствуйте.
Есть два класса: Main и XmlParser. Подскажите, как можно заполнить zurnal и last10 значениями из search и searchCopy соответственно при вызове метода XmlParser.xmlMethod()?

Класс Main:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
    public class Main extends Application{
        //Объявляем переменные для компонентов формы
        Button button;
        Stage window;
        TextArea zurnal;
        TextArea last10;
        TitledPane titledPaneZurnal;
        TitledPane titledPaneLast10;
        TextField timerText;
        Label l1;
     
     
     
    public static void main(String[] args) {
        launch(args);
    }
     
    @Override
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;
        window.setTitle("TimeCheck");
        window.setResizable(false);
        button = new Button("Открыть");
        zurnal = new TextArea(); //Создаем объект текстового поля для текстового поля с журналом
        button.setOnAction(e -> {
            try {
                XmlParser.xmlMethod();
            } catch (ParserConfigurationException e1) {
                e1.printStackTrace();
            } catch (IOException e1) {
                e1.printStackTrace();
            } catch (SAXException e1) {
                e1.printStackTrace();
            } catch (XPathExpressionException e1) {
                e1.printStackTrace();
            }
        });
     
        l1 = new Label("Журнал добавленных материалов");
        last10 = new TextArea(); //Создаем объект текстового поля для последних 10 записей
        VBox layout = new VBox(20);
        layout.getChildren().addAll(l1, zurnal, last10, button);
        Scene scene = new Scene(layout, 700,500);
        window.setScene(scene);
        window.show();
    }



Класс XmlParser:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
    public class XmlParser {
    private static String xmlSource = "http://freerutor.me/rss.xml"; //Ссылка на источник xml
    private static String lastFilm ="";
    public static Main main = new Main();
    static ArrayList<String> searchCopy;
     
     
    public static void xmlMethod() throws ParserConfigurationException, IOException, SAXException, XPathExpressionException {
        // Создаем DOM
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document bbcDoc = builder.parse(xmlSource);
     
        ArrayList<String> search = new ArrayList<String>();
     
        XPath xpath = XPathFactory.newInstance().newXPath();
     
        String expression = "/rss/channel/item"; //выражение для поиска
        NodeList itemNodes = (NodeList) xpath.evaluate(expression, bbcDoc, XPathConstants.NODESET); //создаем список значений
     
     
        for (int i = 0; i < itemNodes.getLength(); i++) {
            String expression2 = "title"; //Ищем заголовки в списке
            Node titleInItemNode = (Node) xpath.evaluate(expression2, itemNodes.item(i), XPathConstants.NODE);
            search.add(titleInItemNode.getTextContent()); // Выводим заголовки
        }
     
        int position = 0;
        boolean flag = false;
        // Определяем последний фильм, по которому будет вестись отбор
        if (search.get(0).trim() != lastFilm.trim())
        {
            if (lastFilm != "") // если переменная не пуста, то мы определяем позицию материала, который считался "последним" в прошлой проверке
            //и копируем строки с 0 по по ту, на которой находится этот самый материал
            {
                position = search.indexOf(lastFilm);
                lastFilm = search.get(0).trim();
                if (position > 0)
                {
                    //searchCopy.clear();
                    searchCopy = new ArrayList<String>(search.subList(0, position));
                    search.clear();
                }
                else
                {
                    searchCopy = new ArrayList<String>(search.subList(0, position + 1));
                    search.clear();
                }
            }
            else //Если в переменной ничего нет, то мы записываем в нее название последнего добавленного материала на сайт
            {
                lastFilm = search.get(0).trim();
                position = search.indexOf(lastFilm);
                searchCopy = new ArrayList<String>(search.subList(0, position + 1));
            }
            flag = true;
     
        }
    }



Единственное, до чего я додумался - это сделать метод xmlMethod возвращаемым, но проблема в том, что return вроде как может вернуть только 1 значение, а ArrayList у меня 2. Конечно, можно их запихнуть в один общий ArrayList, но хотелось бы без такого обойтись.
...
Рейтинг: 0 / 0
29.04.2018, 18:22
    #39638353
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
- Вариантов масса
- Идея возвращать результат работы метода - здравая
- Если нужно вернуть много объектов, то, обычно, их объединяют в структуру или используют грязный хак в виде Tuple
- Почему нужен список списков не очень понятно, если можно просто склеить списки
- К коду вообще много претензий
- Как альтернатива возвращаемому результату - callback - параметром метода передаете какую-нибудь лямду Consumer<String>.
Реализация лямды добавляет в TextArea - пользователи лямбды добавляют в нее строки.
...
Рейтинг: 0 / 0
29.04.2018, 20:36
    #39638368
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz- Вариантов масса
- Идея возвращать результат работы метода - здравая
- Если нужно вернуть много объектов, то, обычно, их объединяют в структуру или используют грязный хак в виде Tuple
- Почему нужен список списков не очень понятно, если можно просто склеить списки
- К коду вообще много претензий
- Как альтернатива возвращаемому результату - callback - параметром метода передаете какую-нибудь лямду Consumer<String>.
Реализация лямды добавляет в TextArea - пользователи лямбды добавляют в нее строки.

Если можно, приведите, пожалуйста, пример реализации одного из этих вариантов.
По поводу кода я знаю, на java пишу 7-ой день, обычно с C# работаю, там с этим гораздо проще все. Но курсач сказали писать на джаве, вот и мучаюсь)

Ну и, конечно, не против выслушать претензии к коду, новая информация лишней никогда не будет.
...
Рейтинг: 0 / 0
01.05.2018, 08:37
    #39638620
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
button.setOnAction(e -> {
                XmlParser.xmlMethod(s -> last10.appendText(s));
});


public static void xmlMethod(Consumer<String> searchResultsConsumer) {
    ...
    searchResultsConsumer.accept(recordFound);

}



Замечания по коду
- Строки нельзя сравнивать через == и !=, потому что эти операторы сравнивают ссылки на объекты. Одинаковая строка можен быть представлена разными объектами.
- Избегайте статики - классов, методов и т.п. по возможности. Статические методы имеют ряд ограничений.
- Используйте максимально абстрактный нужный интерфейс при объявлении перменых List<String> text = new ArrayList<>();
- Изучите биндиг в JavaFX это очень полезный инструмент
- Избегайте переиспользование кода копированием (копи-паста) - вот тут у вас условие влияет только на единицу, но скопировали вы целый блок, хотя условие можно было применить только к аргументу
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
 if (position > 0)
                {
                    //searchCopy.clear();
                    searchCopy = new ArrayList<String>(search.subList(0, position));
                    search.clear();
                }
                else
                {
                    searchCopy = new ArrayList<String>(search.subList(0, position + 1));
                    search.clear();
                }


Код: java
1.
..subList(0, position + position > 0 ? 0 : 1)..


- Исключения можно ловить одним блоком:
https://docs.oracle.com/javase/7/docs/technotes/guides/language/catch-multiple.html
...
Рейтинг: 0 / 0
01.05.2018, 10:49
    #39638640
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
button.setOnAction(e -> {
                XmlParser.xmlMethod(s -> last10.appendText(s));
});


public static void xmlMethod(Consumer<String> searchResultsConsumer) {
    ...
    searchResultsConsumer.accept(recordFound);

}



Замечания по коду
- Строки нельзя сравнивать через == и !=, потому что эти операторы сравнивают ссылки на объекты. Одинаковая строка можен быть представлена разными объектами.


Вчера весь вечер убил на то, чтобы понять, почему строки сравниваются неправильно. Пока не додумался загуглить на эту тему)
equals будет же достаточно для сравнения? Потому как где-то видел примечание, что его надо переопределять, но вроде даже без этого сравнение идет корректно.

По Вашему коду recordFound - это что? Если на его место поставить, например, search, то в last10 у меня при нажатии на кнопку появляется лишь "[]".
...
Рейтинг: 0 / 0
01.05.2018, 14:09
    #39638696
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Fanat_96По Вашему коду recordFound - это что?

То что вы хотите добавить в текстовое поле.

Fanat_96Если на его место поставить, например, search, то в last10 у меня при нажатии на кнопку появляется лишь "[]".
Это я не знаю. Такие вопросы лушче пошаговому отладчику задавать.
...
Рейтинг: 0 / 0
01.05.2018, 15:00
    #39638703
fixxer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz- Используйте максимально абстрактный нужный интерфейс при объявлении перменых List<String> text = new ArrayList<>();


А вот это зачем? В сигнатурах метода понятно, но в для локальных переменных зачем? И как это соотносится с новой линией партии?
Код: java
1.
var text = new ArrayList<String>();
...
Рейтинг: 0 / 0
01.05.2018, 15:46
    #39638712
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz,

Если мне нужно вернуть два ArrayList, значит можно написать примерно так?
Код: java
1.
public static void xmlMethod(Consumer<String> searchResultsConsumer, Consumer<String> searchCopyConsumer )


И вызвать так
Код: java
1.
2.
button.setOnAction(e -> {
            XmlParser.xmlMethod(s -> System.out.println(s), s1 -> System.out.println(s1));



Вроде как работает, но мало ли и тут накосячил)

По сути, вместо Consumer<String> я могу написать Consumer<ArrayList>, так как я их возвращаю. Правда, потом надо еще будет String.valueOf() использовать. Результаты выводит идентичные. Собственно, вопрос: есть ли разница?


И еще: результат (в обоих случаях), возвращается в виде строки.
Я разбил его таким вот образом:
Код: java
1.
2.
3.
4.
String[] searchMain;
button.setOnAction(e -> {
            XmlParser.xmlMethod(s -> zurnal.setText(String.valueOf(searchMain =(s.split(",")))), s1 -> last10.setText(s1));
}


В результате в searchMain записало все 15 передаваемых элементов. Но может есть более простой способ построчной записи напрямую в textarea?
...
Рейтинг: 0 / 0
01.05.2018, 15:56
    #39638717
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
fixxerА вот это зачем?

Смотри SOLID Low Coupling
Чем более конкретный тип ты используешь, тем больше ты к нему привязан, тем больше тебе нужно делать изменений в случае изменения самого конкретного типа или его API. То есть цепная реакция от изменений имеет больший радиус. Когда же используешь более абстрактный тип, то связь с конкретным типом теряется и изменения конкретного типа уже никак не касаются остального кода и цепной реакции при внедрнении изменений не происходит. Ну, то есть она минимизирована.

fixxerВ сигнатурах метода понятно, но в для локальных переменных зачем?

Я не вижу разницы между полями, локальными переменными и аргументами. Все они являются переменными. И то что одна и та же переменная сегодня аргумент, завтра локальная переменная, послезавтра уже поле - вполня обычная ситуация при рефакторинге.

fixxer И как это соотносится с новой линией партии?
Код: java
1.
var text = new ArrayList<String>();


Как всегда: палка о двух концах.
https://www.beyondjava.net/blog/adding-type-inference-to-java-good-or-evil/
...
Рейтинг: 0 / 0
01.05.2018, 16:18
    #39638725
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Fanat_96,

Как я написал изначально, способов реализовать передачу значения существует много. Ваша задача выбрать наиболее простой с одной стороны. Но и наиболее понятный стороннему читателю с другой стороны. В промышленном программировании понятность и очевидность кода это очень важный критерий качества кода, который при современных вычислительных мощностях, зачастую, намного важнее, например, производительности. А иногда даже корректности. (важность меряется экономический эффективностью). Так как код живет долго и подвергается постоянным изменениям. И стоимость этих изменений является основной статьей затрат при разработке.

В качестве же курсовой работы правильное решение зависит от того какая у вас цель.
Сделать и забыть.
Сделать и забыть, но чтобы работало.
Научится делать хорошо. В этом случае, наверное, стоит прочитать такие книги как Clean Code и применять рекомендации из этих книг к своему коду.

Для новичков есть один очень простой и классный совет. Чем больше ваш код похож на натуральный язык, тем он понятнее.
И вот этот ваш код с натуральным языком имеет мало общего.
Код: java
1.
2.
3.
button.setOnAction(e -> {
            XmlParser.xmlMethod(s -> zurnal.setText(String.valueOf(searchMain =(s.split(",")))), s1 -> last10.setText(s1));
}


А выглядеть он мог бы, например так:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
button.setOnAction(this::searchButtonHandler);

void searchButtonHandler(Event e){
         RssXmlPrarser.searchForRssChannels(this::applyItemsToJournal, last10::setText);
}

void applyItemsToJournal(String allItems){
   journal.setText(allItems.split(SPLIT_EXPRESSION));
}



Но мне сложно написать понятные идентификаторы, потому что вашей предметной области я не знаю.
...
Рейтинг: 0 / 0
01.05.2018, 16:34
    #39638734
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
И еще код мог бы быть совсем простым и понятным, если бы использовался MVVM паттерн. Который очень хорошо вписывается в JavaFX с той лишь оговоркой что в примитивных случаях вроде вашего разделением Model и ModelView можно принебречь.
...
Рейтинг: 0 / 0
01.05.2018, 20:57
    #39638806
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz,

честно говоря, даже не знал, что так писать можно)
я скорее делаю что-то среднее между 2 и 3 пунктом. Хочется, чтобы оно работало, но и хочется понимать, почему я так написал, а не как-то иначе. Но и "вылизывать" код досконально тоже желания нет.

Если менять под меня, то получается, что будет тип такого?
Код: java
1.
2.
3.
    void applyItemsToJournal(String allItems){
        zurnal.setText(String.valueOf(allItems.split(",")));
    }


Если да, то в ответ в last10 я получаю то, что надо, а вот в zurnal - "[Ljava.lang.String;@4296565b".
...
Рейтинг: 0 / 0
01.05.2018, 21:31
    #39638827
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Пока что метод таким вот сделал
Код: java
1.
2.
3.
4.
5.
void applyItemsToJournal(String allItems){
            String[] journalArray = allItems.split(",");
            for (int i = 0 ; i<journalArray.length; i++) {
                journal.appendText(journalArray[i]+"\n");
            }
...
Рейтинг: 0 / 0
02.05.2018, 08:18
    #39638875
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Fanat_96,

Код: java
1.
journal.setText(allItems.replace(",", "\n"));


Не одно и то же?
...
Рейтинг: 0 / 0
03.05.2018, 11:30
    #39639257
Fanat_96
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнить textarea из другого класса
Blazkowicz,
Спасибо Вам за помощь)
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Заполнить textarea из другого класса / 15 сообщений из 15, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]