Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Ihmemies
Oct 6, 2012

Is Java's formatter just weird or what, compared to ANSI C :D

Or is there some other way to specify "precision" than this hot garbage:

Java code:
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
for (var param : args) {                  
      System.out.printf("#%" + col0_width + "d | %-" + col1_width +"s #\n", i, param);
       i++;
       // avoid printing extra dividers
       if (i <= args.length) {
           System.out.printf("#%s+%s#\n",
                       "-".repeat(col0_width+1),
                       "-".repeat(col1_width+2));
        }
}
System.out.println("#".repeat(col0_width + col1_width + ROW_PADDING));
It prints out a table like this from command params. Specifying the precision/padding/whatever is just terrible... in C's printf you can do something like "%.*c", 17, '#' and then it prints 17 #'s.

Or "#%.d | #%.s #\n", col0_width, i, col1_width, param" instead of.. whatever you have to do with Java.

code:
#########################################
#  1 | Algeria                          #
#----+----------------------------------#
#  2 | Angola                           #
#----+----------------------------------#
#  3 | Benin                            #
#----+----------------------------------#
#  4 | Bolivia                          #
#----+----------------------------------#
#  5 | Chad                             #
#----+----------------------------------#
#  6 | Democratic Republic of the Congo #
#----+----------------------------------#
#  7 | Finland                          #
#----+----------------------------------#
#  8 | Lesotho                          #
#----+----------------------------------#
#  9 | Romania                          #
#----+----------------------------------#
# 10 | Uzbekistan                       #
#########################################
Not a big deal really but if they had to copy C why they didn't copy it properly :argh:

Ihmemies fucked around with this message at 18:30 on Jan 14, 2023

Adbot
ADBOT LOVES YOU

Ihmemies
Oct 6, 2012

Thanks. It was a school exercise so I assume using the formatter was the idea behind it. Anyways, it is not good :( But I'll live. I've been doing an ANSI C course too so I got somewhat used to it.. just type what you want to be printed, then enter the list of variables separated by commas. Stringutils looks handy, thanks.

Ihmemies
Oct 6, 2012

School exercises have progressed. I made a MovieAnalytics class, as instructed - using streams and Collectors.groupingBy. Automatic grading gave it a pass.

The three methods I implemented look like each other. The .collect method differrs, and sort has descending order in some.. also the printouts differ.

Does it make any sense to try to make some kind of combination of these three? The code looks repetitive, but does it matter?

If I "must" do some kind of combination method, how could I get started? I have no functioning ideas after trying. It gets too hard for me to choose elegantly between different groupingBy() methods with streams...

Also the .sorted() is not very good, but I could not figure out another way to sort those...

Java code:
/* 
    Member function void printCountByDirector(int n) that prints out the n directors that
    have directed the most movies, in descending order of the number of movies.
    Directors with equally many movies are ordered by their names using the
    default order of the String objects. Each director is printed in the ###m 
    "director: x movies", where x is the number of movies directed by that 
    particular director. The output is printed in a single line that ends 
    to a new line character.
    */
    public void printCountByDirector(int n) {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getDirector, Collectors.counting()))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie count descending    
                int countCompare = e2.getValue().compareTo(e1.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie count is equal, sort by director name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .limit(n)
            .forEach(e -> System.out.print(e.getKey() + ": " + e.getValue() + " movies\n"));
    }


    /* 
    Member function void printAverageDurationByGenre() that prints out all movie genres of 
    the database in ascending order of the average duration of movies in that 
    genre. Movies in the same genre are ordered by title using the default order
    of the String objects. Each genre is printed in the ###m "genre: average",
    where average is the average duration of movies in that genre, using two 
    decimals of precision. The output is printed in a single line that ends
    to a new line character.
    */
    public void printAverageDurationByGenre() {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getGenre, Collectors.averagingDouble(Movie::getDuration)))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie average duration ascending    
                int countCompare = e1.getValue().compareTo(e2.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie average duration is equal, sort by genre name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .forEach(e -> System.out.print(e.getKey() + ": " + String.format("%.2f", e.getValue()).replace(',', '.') + "\n"));
    }


    /*
    Member function void printAverageScoreByGenre() that prints out all movie
    genres of the database in descending order of the average rating scores
    of movies in that genre. Genres with the same average rating are ordered 
    by genre name using the default order of the String objects. Each genre 
    is printed in the ###m "genre: average", where average is the average
    rating score of movies in that genre, using two decimals of precision. 
    The output is printed in a single line that ends to a new line character.
    */
    public void printAverageScoreByGenre() {
        movies.stream()
            .collect(Collectors.groupingBy(Movie::getGenre, Collectors.averagingDouble(Movie::getScore)))
            .entrySet()
            .stream()
            .sorted((e1, e2) -> {
                // sort by movie count descending    
                int countCompare = e2.getValue().compareTo(e1.getValue());                            
                if (countCompare != 0) {
                    return countCompare; 
                // IF movie count is equal, sort by director name ascending
                } 
                else {
                    return e1.getKey().compareTo(e2.getKey()); 
                }
            })
            .forEach(e -> 
                System.out.print(
                    e.getKey() +
                    ": " + 
                    String.format("%.2f", e.getValue()).replace(',', '.') +
                     "\n"));
    }

Ihmemies
Oct 6, 2012

Eezee posted:

The only thing i would change is your sort method. You can do better using the built in Comparator functions. See:
https://www.baeldung.com/java-8-comparator-comparing

Refactoring other stuff there would just make it more complicated for marginally less repetition.

Thanks, I found out about the Java8's Comparator comparing but I was too dense to understand how to use it. I will try again :v:

Ihmemies
Oct 6, 2012

So finally we're doing some javafx-maven-whatever programs. The first is a very simple calculator. It is tested on school's black book CalculatorTest tester.

code:
Failures (2):
  JUnit Jupiter:CalculatorTest:Testing field basics
    MethodSource [className = 'fi.tuni.prog3.calc.CalculatorTest', methodName = 'checkFields', methodParameterTypes = '']
    => java.lang.ClassCastException: class javafx.scene.control.TextField cannot be cast to class javafx.scene.control.Label (javafx.scene.control.TextField and javafx.scene.control.Label are in unnamed module of loader java.net.FactoryURLClassLoader @6bdf28bb)
       fi.tuni.prog3.calc.CalculatorTest.checkFields(CalculatorTest.java:39)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
       java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       java.base/java.lang.reflect.Method.invoke(Method.java:568)
       org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
       org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
       org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
       org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
       org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
       [...]
  JUnit Jupiter:CalculatorTest:Testing operations
    MethodSource [className = 'fi.tuni.prog3.calc.CalculatorTest', methodName = 'checkOperations', methodParameterTypes = '']
    => java.lang.ClassCastException: class javafx.scene.control.TextField cannot be cast to class javafx.scene.control.Label (javafx.scene.control.TextField and javafx.scene.control.Label are in unnamed module of loader java.net.FactoryURLClassLoader @6bdf28bb)
       fi.tuni.prog3.calc.CalculatorTest.checkOperations(CalculatorTest.java:102)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
       java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
       java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
       java.base/java.lang.reflect.Method.invoke(Method.java:568)
       org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
       org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
       org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
       org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
       org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
       [...]

Do you have any ideas what might cause that error? The app looks like this in Scene Builder:



I read the values like this on my controller class:

code:
String op1Str = fieldOp1.getText();
String op2Str = fieldOp2.getText();
Then I convert them to double, do calculations, convert back to String and write it to the result textfield:

code:
fieldRes.setText(result.toString());
It appears to be working correctly on my PC.

Ihmemies
Oct 6, 2012

Jabor posted:

It's not on your code. The crash is in the tester code. Do you have access to the tester source?

If I had to guess blind, I'd speculate that maybe the result field is supposed to be another label (instead of a textview that the user could type into themselves), but it's possible that it's not that and the tester itself is just poorly-written.

Welp gently caress, the idea was so stupid my brains just smoothed over it. It had to be a LABEL which LOOKS LIKE a text field... sigh. Thanks for the help! :v:

Ihmemies
Oct 6, 2012

smackfu posted:

Can you just tel them to stop teaching you poo poo no one uses?

It's hard. Anyways we got to do our own project now where we can do whatever we want. It pulls some jsons from a rest api over the internet, and we display some data in a javafx application.

Anyways, should vscode display tooltips and tell me more about the classes?

For example in our maven project:

ObjectMapper mapper = new ObjectMapper();

tooltips tell only:

com.fasterxml.jackson.databind.ObjectMapper.ObjectMapper()

Not very helpful. What is an ObjectMapper? Why the tooltip doesn't tell me anything about it? I have no idea should it show more, or is something just broken in my vscode.

If I right click and go to definition, it shows just this:

Java code:
 // Failed to get sources. Instead, stub sources have been generated by the disassembler.
 // Implementation of methods is unavailable.
package com.fasterxml.jackson.databind;
public class ObjectMapper extends com.fasterxml.jackson.core.ObjectCodec implements com.fasterxml.jackson.core.Versioned, java.io.Serializable {
  
  private static final long serialVersionUID = 2L;
  
  protected static final com.fasterxml.jackson.databind.AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR;
  
  protected static final com.fasterxml.jackson.databind.cfg.BaseSettings DEFAULT_BASE;
  
  protected final com.fasterxml.jackson.core.JsonFactory _jsonFactory;
  
  protected com.fasterxml.jackson.databind.type.TypeFactory _typeFactory;
  
  protected com.fasterxml.jackson.databind.InjectableValues _injectableValues;
  
  protected com.fasterxml.jackson.databind.jsontype.SubtypeResolver _subtypeResolver;
  
  protected final com.fasterxml.jackson.databind.cfg.ConfigOverrides _configOverrides;
  
  protected final com.fasterxml.jackson.databind.cfg.CoercionConfigs _coercionConfigs;
  
  protected com.fasterxml.jackson.databind.introspect.SimpleMixInResolver _mixIns;
  
  protected com.fasterxml.jackson.databind.SerializationConfig _serializationConfig;
  
  protected com.fasterxml.jackson.databind.ser.DefaultSerializerProvider _serializerProvider;
  
  protected com.fasterxml.jackson.databind.ser.SerializerFactory _serializerFactory;
  
  protected com.fasterxml.jackson.databind.DeserializationConfig _deserializationConfig;
  
  protected com.fasterxml.jackson.databind.deser.DefaultDeserializationContext _deserializationContext;
  
  protected java.util.Set<java.lang.Object> _registeredModuleTypes;
  
  protected final java.util.concurrent.ConcurrentHashMap<com.fasterxml.jackson.databind.JavaType,com.fasterxml.jackson.databind.JsonDeserializer<java.lang.Object>> _rootDeserializers;
  
  public ObjectMapper() {
  }
Edit:

I had to go vscode settings -> search for download sources -> enable java > eclipse & java > maven download sources.

Then I had to go find my maven's settings.xml and add this (it was in some weird random folder in my C:\users\username\.m2\ folder.)

code:
<settings>
    <!-- ... other settings omitted ... -->
    <profiles>
        <profile>
            <id>downloadSources</id>
            <properties>
                <downloadSources>true</downloadSources>
                <downloadJavadocs>true</downloadJavadocs>
            </properties>
        </profile>
    </profiles>

    <activeProfiles>
            <activeProfile>downloadSources</activeProfile>
    </activeProfiles>
</settings>

Ihmemies fucked around with this message at 09:41 on Apr 22, 2023

Ihmemies
Oct 6, 2012

Qt, IntelliJ IDEA, Netbeans, Visual Studio just feel like "legacy" apps compared to VSCode. Like, I haven't even tested them myself, but that was my impression! I got the java documentation to work in vscode, so it was pretty nice after all. I don't know what I'm missing. What am I missing while using vscode instead of intellij idea for example?

As a student I don't really have money to pay for software, so vscode is nice in that respect too, since it's completely free and open source.



We coded a javafx app which pulls open data from REST API and displays our university's degree programmes and courses. You can add and remove courses and mark them as completed, and it shows your progression. Supports multiple users (for no real benefit). Took maybe 2 weeks of coding from three guys. We didn't make a spec first, so it was kind of uhh "let's try if this works" approach. Worked well enough.

Ihmemies
Oct 6, 2012

hooah posted:

In my (limited) experience, VS Code requires at least a few plugin to get it working for Java, then you have to write your own run commands or whatever. IntelliJ, even the community edition, understands how to run and debug Java programs out of the box, and makes it very easy to do so.

I installed some set of Java tools which vscode suggested. They seemed to work fine, except for the documentation issue, Maven didn't know how to download docs automatically. Only missing debugger feature was that it would be nice to have some kind of "developer mode" in javafx where you can "inspect" elements in the javafx app, like in a webpage in a browser or something. There was some maven plugin for that but it hadn't been updated in years and supported only ancient java versions.

Ihmemies
Oct 6, 2012

fletcher posted:

IntelliJ just works so well out of the box. I would ditch VSCode for Java development so you don't have to waste time trying to get it to do what IntelliJ does by default. The Community Edition is also free.

I have no idea when school will force more java for us, so I have no idea when I will do more java coding. Maybe never? My vscode is set up now, so what is the point of changing and learning to use some new tool? Just because it's new and fancy is not a good enough reason.

Ihmemies
Oct 6, 2012

I tried searching for reasons why IntelliJ is better, but I could not find a single concrete example on why it is better. Even better would be a list of benefits with concrete examples. Surely someone must have made one?

Or maybe even a list of what’s missing from vscode, and why the missing feature matters? Even chatgpt could not give answers.

Ihmemies
Oct 6, 2012

I have a problem deciding what is the least crap way of implementing choicebox values in javafx. Depending on user selections and choiceboxes, I need to have a variable_id (for API calls) associated with the choice, or a LineChart.class for example, so I know what kind of XYChart the user wants to draw.

How would you store the choices? Enums? Classes? Something else? Enums work ok'ish with strings, like this:

Java code:
public enum AxisType {
    CONSUMPTION("Consumption", "124", "Electricity Consumption (1 Hour)"),
    PRODUCTION("Production", "74", "Electricity Production (1 Hour)"),
    PRICE("Price", "00", ""),
    TEMPERATURE("Temperature", "00", ""),
    WIND("Wind", "00", "");

    private final String label;
    private final String variableId;
    private final String description;

    AxisType(String label, String variableId, String description) {
        this.label = label;
        this.variableId = variableId;
        this.description = description;
    }

    public String getVariableId() {
        return variableId;
    }

    public String getDescription() {
        return description;
    }

    @Override
    public String toString() {
        return label;
    }

    public static List<String> stringValues() {
        List<String> stringValues = new ArrayList<>();
        for (AxisType type : AxisType.values()) {
            stringValues.add(type.toString());
        }
        return stringValues;
    }
}
But if I want to store a class - for example LineChart.class or AreaChart.class - I can't get the constructor to work with a Class<?> or Class<? extends XYChart<Number, Number>>. It always crashes and burns because of invalid syntax.

This seems to work:

Java code:
public enum ChartType {
    LINE_CHART("Line chart") {
        @Override
        public XYChart<Number, Number> createChart() {
            return new LineChart<>(new NumberAxis(), new NumberAxis());
        }
    },
    AREA_CHART("Area chart") {
        @Override
        public XYChart<Number, Number> createChart() {
            return new AreaChart<>(new NumberAxis(), new NumberAxis());
        }
    };

    private final String label;

    ChartType(String label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return label;
    }

    public abstract XYChart<Number, Number> createChart();

    public static List<String> stringValues() {
        List<String> stringValues = new ArrayList<>();
        for (ChartType type : ChartType.values()) {
            stringValues.add(type.toString());
        }
        return stringValues;
    }
}
Then this in the actual program:

Java code:
ChartType selectedChartType = chartTypeChoiceBox.getValue();
XYChart<Number, Number> chart = selectedChartType.createChart();
Why it is so hard to store classes? How else would I figure out what kind of chart I need to draw, based on user choice? Any pro tips..?

This thing is a 4 man course project, still on prototype stage, so I can try out all kinds of stuff.

Ihmemies fucked around with this message at 06:14 on Sep 17, 2023

Ihmemies
Oct 6, 2012

Well that seems to work too. We are using 17 so I guess I can research sealed classes too. Thanks :D

Adbot
ADBOT LOVES YOU

Ihmemies
Oct 6, 2012

We're doing a desktop app for course, because web abbs were explicitly forbidden. We ended up using javafx because that's what a few guys have used earlier.



Is there some "easy" way to specify the line/area colors? I looked at assigning an ID to each data series (line) depending on datatype, and then applying the color for that id with CSS. Like nuclear = YELLOW, wind = GREEN, hydro = BLUE etc.

But no, this poo poo rear end piece of garbage apparently gives data series id's automatically from 0..n, based on the add order to chart.

So I'd have to make some kind of hell construct to figure out the id of each added series... etc. I don't even want to think about it. The chart can have any amount of series depending on datatype. Each datatype should have a specific color always...

Who ***** thought that it is ***** good idea to label the series automatically with incrementing id, which depends on add order...

Already thinking about implementing a webview inside the javafx app.

Ihmemies fucked around with this message at 11:31 on Oct 20, 2023

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply